如何在 Seaborn 的 displot 中添加平均值和中位数线

14
有没有办法在Seaborn的displot中添加平均值和中位数?
penguins = sns.load_dataset("penguins")
g = sns.displot(
    data=penguins, x='body_mass_g',
    col='species',  
    facet_kws=dict(sharey=False, sharex=False)
)

enter image description here

基于在seaborn FacetGrid distplots中添加均值和变异性,我可以定义一个FacetGrid并映射一个函数。我能否将自定义函数传递给displot
我之所以尝试直接使用displot是因为这些图表的样式默认情况下更漂亮,不需要调整刻度标签大小、轴标签大小等,并且与我正在制作的其他图表在视觉上保持一致。
def specs(x, **kwargs):
    ax = sns.histplot(x=x)
    ax.axvline(x.mean(), color='k', lw=2)
    ax.axvline(x.median(), color='k', ls='--', lw=2)

g = sns.FacetGrid(data=penguins, col='species')
g.map(specs,'body_mass_g' )

enter image description here

2个回答

12

选项1

  • 使用plt。代替ax
    • 在原始代码中,vlines适用于histplotax,但在此处,图形是在.map之前创建的。
penguins = sns.load_dataset("penguins")
g = sns.displot(
    data=penguins, x='body_mass_g',
    col='species',  
    facet_kws=dict(sharey=False, sharex=False)
)

def specs(x, **kwargs):
    plt.axvline(x.mean(), c='k', ls='-', lw=2.5)
    plt.axvline(x.median(), c='orange', ls='--', lw=2.5)

g.map(specs,'body_mass_g' )

选项2

  • 这个选项说得更详细,但更加灵活,因为它允许从数据源中访问和添加信息,而不仅仅是用于创建displot的那个数据源。
import seaborn as sns
import pandas as pd

# load the data
pen = sns.load_dataset("penguins")

# groupby to get mean and median
pen_g = pen.groupby('species').body_mass_g.agg(['mean', 'median'])

g = sns.displot(
    data=pen, x='body_mass_g',
    col='species',  
    facet_kws=dict(sharey=False, sharex=False)
)
# extract and flatten the axes from the figure
axes = g.axes.flatten()

# iterate through each axes
for ax in axes:
    # extract the species name
    spec = ax.get_title().split(' = ')[1]
    
    # select the data for the species
    data = pen_g.loc[spec, :]
    
    # print data as needed or comment out
    print(data)
    
    # plot the lines
    ax.axvline(x=data['mean'], c='k', ls='-', lw=2.5)
    ax.axvline(x=data['median'], c='orange', ls='--', lw=2.5)

两种选项的输出

enter image description here

资源


3

您可以使用sns.FacetGrid.facet_data遍历子图的索引和底层数据。

这与sns.FacetGrid.map的工作方式非常接近。 sns.FacetGrid.facet_data是一个生成器,它产生一个元组(i, j, k),其中包含行、列、色调索引和datadata是一个DataFrame,它是每个子图对应的完整数据的子集。

import seaborn as sns
import pandas as pd


pen = sns.load_dataset("penguins")

# Set our x_var for later use
x_var = "body_mass_g"

g = sns.displot(
    data=pen,
    x=x_var,
    col="species",
    facet_kws=dict(sharey=False, sharex=False),
)

for (row, col, hue_idx), data in g.facet_data():
    # Skip empty data
    if not data.values.size:
        continue

    # Get the ax for `row` and `col`
    ax = g.facet_axis(row, col)
    # Set the `vline`s using the var `x_var`
    ax.axvline(data[x_var].mean(), c="k", ls="-", lw=2.5)
    ax.axvline(data[x_var].median(), c="orange", ls="--", lw=2.5)

这将输出:

mean和median的FacetGrid叠加vlines

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接