如何连接箱线图的中位数值

8
似乎将箱形图的均值连接起来是一件简单的事情,但我却不知道如何在pandas中实现此绘图。
我使用以下语法进行箱形图以便自动生成Y与X设备的箱形图,无需对数据框进行外部处理:
df.boxplot(column='Y_Data', by="Category", showfliers=True, showmeans=True)

输入图片描述

我想到的一种方法是通过从箱线图中获取平均值来绘制折线图,但我不确定如何从图表中提取这些信息。

2个回答

6
您可以保存从df.boxplot()返回的轴对象,并使用相同的轴将均值绘制为线图。我建议使用Seaborn的pointplot来绘制这些线条,因为它可以很好地处理分类x轴。首先让我们生成一些示例数据:
import pandas as pd
import numpy as np
import seaborn as sns

N = 150
values = np.random.random(size=N)
groups = np.random.choice(['A','B','C'], size=N)
df = pd.DataFrame({'value':values, 'group':groups})

print(df.head())
  group     value
0     A  0.816847
1     A  0.468465
2     C  0.871975
3     B  0.933708
4     A  0.480170
              ...

接下来,制作箱线图并保存轴对象:

ax = df.boxplot(column='value', by='group', showfliers=True, 
                positions=range(df.group.unique().shape[0]))

注意:在Pyplot/Pandas的boxplot()中有一个奇怪的positions参数,可能导致偏差。请参阅此讨论,其中包括我在此处使用的解决方法。
最后,使用groupby获取类别平均值,然后将平均值与覆盖在箱线图上的折线图连接起来:
sns.pointplot(x='group', y='value', data=df.groupby('group', as_index=False).mean(), ax=ax)

箱线图

您的标题提到了“中位数”,但在帖子中您谈论的是类别均值。我在这里使用了均值;如果您想绘制中位数,请将groupby聚合更改为median()


一个很好的回答!我还没有使用过Seaborn包,但看起来这是一个逻辑上的选择来完成这个任务,而且我已经有了所有的依赖项。谢谢! - Patratacus

0

您可以通过使用绘制它们的matplotlib.lines.Line2D对象的.get_data()属性来获取中位数的值,而无需使用seaborn。

假设您创建了一个箱线图bp=plt.boxplot(data)。那么,bp是一个包含medians键的dict,其中还有其他键。该键包含一个list,其中包含matplotlib.lines.Line2D,您可以按以下方式提取(x,y)位置:

bp=plt.boxplot(data)
X=[]
Y=[]
for m in bp['medians']:
    [[x0, x1],[y0,y1]] = m.get_data()
    X.append(np.mean((x0,x1)))
    Y.append(np.mean((y0,y1)))
plt.plot(X,Y,c='C1')

对于任意数据集(data),此脚本生成此图。希望有所帮助!

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