使用 Seaborn 的 FacetGrid 自定义注释 [英] Customizing annotation with Seaborn's FacetGrid

查看:37
本文介绍了使用 Seaborn 的 FacetGrid 自定义注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python中的Seaborn模块自定义一些图形,但是我没有运气来创建自定义标签或注释.我有一些生成下图的代码:

  plot = sns.FacetGrid(数据=数据,col ='机器人',margin_titles = True).set_titles('Human','Bot')bins = np.linspace(0, 2000, 15)情节= plot.map(plt.hist,'friends_count',color ='black',lw = 0,bins = bins)plot.set_axis_labels('数字跟随','计数')sns.despine(left = True,bottom = True)

我想做两件事:1. 替换默认因子标签,例如"bot = 0.0"(带有有意义的文本),并为每个类别在平均数之后绘制垂直线.

这是一个独立的例子:

将pandas导入为pd将 seaborn 作为 sns 导入导入matplotlib.pyplot作为plt假= pd.DataFrame({'val':[1,2,2,3,3,2,1,1,2,3],'group':[0,0,0,0,0,1,1,1,1,1]})plot = sns.FacetGrid(data = fake, col = 'group', margin_titles = True).set_titles('zero', 'one')plot = plot.map(plt.hist, 'val', color = 'black', lw = 0)sns.despine(左=真,下=真)

有人知道如何自定义 FacetGrids 吗?

解决方案

关于 set_titles 的一些事情.

首先,默认标题是在 FacetGrid.map 方法中绘制的,因此,如果要更改标题,则必须在< 绘图,否则它们将被覆盖.

第二,如果您查看该方法的文档字符串,它不只是采用任意的标题列表.它提供了一种使用列变量名称和值更改标题呈现方式的方法:

模板:字符串具有格式键{col_var}和{col_name}(如果使用`col`多面变量)和/或{row_var}和 {row_name} (如果使用 `row` 分面变量).

因此,拥有有意义的文本"的最简单方法是在数据框中使用有意义的数据.以随机数据为例:

  df = pd.DataFrame({'val':np.random.randn(100),'group':np.repeat([0,1],50)})

如果您希望组"为 zeroone,您应该更改该列,或创建一个新列:

  df ["group"] = df ["group"].map({0:"zero",1;"one"})

然后说你不想在标题中有变量名,使用 FacetGrid.set_titles 的正确方法是

g = sns.FacetGrid(data=df, col='group')g.map(plt.hist, 'val', color='black', lw=0)g.set_titles('{col_name}')

如果您不想更改正在绘制的数据,则必须直接在matplotlib轴上设置属性,例如:

 对于斧头,zip格式的标题(g.axes.flat,['zero','one']):ax.set_title(标题)

请注意,这比上述方法不太可取,因为您必须非常小心地确保列表的顺序正确并且不会改变,而从数据帧本身获取信息将是更加健壮.

要绘制均值,您需要创建一个可以传递给 FacetGrid.map 的小函数.有

I'm trying to customize some figures with the Seaborn module in Python, but I haven't had luck creating custom labels or annotations. I've got some code that generates the following figure:

plot = sns.FacetGrid(data = data, col = 'bot', margin_titles = True).set_titles('Human', 'Bot')
bins = np.linspace(0, 2000, 15)
plot = plot.map(plt.hist, 'friends_count', color = 'black', lw = 0, bins = bins)
plot.set_axis_labels('Number Following', 'Count')
sns.despine(left = True, bottom = True)

I'd like to do two things: 1. replace the default factor labels, e.g. 'bot = 0.0', with meaningful text, and 2. draw vertical lines at the mean number following for each category.

Here's a self-contained example:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

fake = pd.DataFrame({'val': [1, 2, 2, 3, 3, 2, 1, 1, 2, 3], 'group': [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]})
plot = sns.FacetGrid(data = fake, col = 'group', margin_titles = True).set_titles('zero', 'one')
plot = plot.map(plt.hist, 'val', color = 'black', lw = 0)
sns.despine(left = True, bottom = True)

Anyone know how to customize FacetGrids?

解决方案

A few things about set_titles.

First, the default titles are drawn in the FacetGrid.map method, so if you want to change the titles, you have to call set_titles after plotting, or else they will be overwritten.

Second, if you look at the docstring for the method, it doesn't just take an arbitrary list of titles. It provides a way to change how the title is rendered using the column variable name and value:

template : string
    Template for all titles with the formatting keys {col_var} and
    {col_name} (if using a `col` faceting variable) and/or {row_var}
    and {row_name} (if using a `row` faceting variable).

So the easiest way to have "meaningful text" is to use meaningful data in your dataframe. Take this example with random data:

df = pd.DataFrame({'val': np.random.randn(100),
                   'group': np.repeat([0, 1], 50)})

If you want "group" to be zero and one, you should just change that column, or make a new one:

df["group"] = df["group"].map({0: "zero", 1; "one"})

Then say you don't want to have the variable name in the title, the proper way to use FacetGrid.set_titles would be

g = sns.FacetGrid(data=df, col='group')
g.map(plt.hist, 'val', color='black', lw=0)
g.set_titles('{col_name}')

If you don't want to change the data you're plotting, then you'll have to set the attributes on the matplotlib axes directly, something like:

for ax, title in zip(g.axes.flat, ['zero', 'one']):
    ax.set_title(title)

Note that this is less preferable to the above method because you have to be very careful about making sure the order of your list is correct and that it isn't going to change, whereas getting the information from the dataframe itself will be much more robust.

To plot the mean, you'll need to create a small function that can be passed to FacetGrid.map. There are multiple examples of how to do this in the tutorial. In this case, it's quite easy:

def vertical_mean_line(x, **kwargs):
    plt.axvline(x.mean(), **kwargs)

Then all you need is to re-plot:

g = sns.FacetGrid(data=df, col='group')
g.map(plt.hist, 'val', color='black', lw=0)
g.map(vertical_mean_line, 'val')
g.set_titles('{col_name}')

这篇关于使用 Seaborn 的 FacetGrid 自定义注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆