使用Seaborn的FacetGrid自定义注释

时间:2015-07-26 00:21:52

标签: python matplotlib seaborn

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

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)

SQL FIDDLE DEMO

我想做两件事:1。替换默认因子标签,例如'bot = 0.0',带有意义的文本,以及2.在每个类别的平均数后面绘制垂直线。

这是一个独立的例子:

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)

任何人都知道如何自定义FacetGrids?

1 个答案:

答案 0 :(得分:17)

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}')

some bar graphs

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}')

some more bar graphs