绘制groupby对象

时间:2017-05-24 07:49:58

标签: python boxplot pandas-groupby

我想根据标准绘制几个数据集的箱线图。 想象一下类似于以下示例的数据框:

df = pd.DataFrame({'Group':[1,1,1,2,3,2,2,3,1,3],'M':np.random.rand(10),'F':np.random.rand(10)})
df = df[['Group','M','F']]

   Group         M         F
0      1  0.465636  0.537723
1      1  0.560537  0.727238
2      1  0.268154  0.648927
3      2  0.722644  0.115550
4      3  0.586346  0.042896
5      2  0.562881  0.369686
6      2  0.395236  0.672477
7      3  0.577949  0.358801
8      1  0.764069  0.642724
9      3  0.731076  0.302369

在这种情况下,我有三组,所以我想为每个组制作一个箱线图,并且对于M和F,分别在Y轴上设置组,并且对M和F的列进行颜色编码。 This answer非常接近我想要实现的目标,但我更喜欢更强大的东西,适用于具有更多组的更大数据帧。我觉得groupby是要走的路,但我不熟悉groupby对象,我甚至没有切片。 。理想的输出看起来像这样:enter image description here

看起来像几年前,有人遇到了同样的问题,但没有得到答案:( Having a boxplot as a graphical representation of the describe function of groupby

我的问题是:

  1. 如何实施groupby以将所需数据提供给boxplot
  2. 如果我想控制显示的内容而不仅仅是使用默认设置(我甚至不知道它们是什么,我发现文档相当含糊不清),框图的正确语法是什么。具体来说,我可以使用覆盖平均值+/-标准差的方框,并将垂直线保持在中位数值吗?)

2 个答案:

答案 0 :(得分:1)

我认为您应该使用Seaborn库来创建这些类型的自定义图。在您的情况下,我首先将您的数据框融化为适当的格式,然后创建您选择的箱图。

import pandas as pd
import matplotlib.pyplot as plt
Import seaborn as sns
dd=pd.melt(df,id_vars=['Group'],value_vars=['M','F'],var_name='sex')
sns.boxplot(y='Group',x='value',data=dd,orient="h",hue='sex')

情节看起来与您所需的情节类似。 enter image description here

答案 1 :(得分:1)

最后,我通过稍微修改this answer找到了解决方案。它不使用groupby对象,因此准备数据更加繁琐,但到目前为止它看起来对我来说是最好的解决方案。这是:

# here I prepare the data (group them manually and then store in lists)

Groups=[1,2,3]
Columns=df.columns.tolist()[1:]
print Columns
Mgroups=[]
Fgroups=[]

for g in Groups:
    dfgc = df[df['Group']==g]
    m=dfgc['M'].dropna()
    f=dfgc['F'].dropna()
    Mgroups.append(m.tolist())
    Fgroups.append(f.tolist())

fig=plt.figure()
ax = plt.axes()
def setBoxColors(bp,cl):
    plt.setp(bp['boxes'], color=cl, linewidth=2.)
    plt.setp(bp['whiskers'], color=cl, linewidth=2.5)
    plt.setp(bp['caps'], color=cl,linewidth=2)
    plt.setp(bp['medians'], color=cl, linewidth=3.5)

bpl = plt.boxplot(Mgroups, positions=np.array(xrange(len(Mgroups)))*3.0-0.4,vert=False,whis='range', sym='', widths=0.6)
bpr = plt.boxplot(Fgroups, positions=np.array(xrange(len(Fgroups)))*3.0+0.4,vert=False,whis='range', sym='', widths=0.6)
setBoxColors(bpr, '#D7191C') # colors are from http://colorbrewer2.org/
setBoxColors(bpl, '#2C7BB6')

# draw temporary red and blue lines and use them to create a legend
plt.plot([], c='#D7191C', label='F')
plt.plot([], c='#2C7BB6', label='M')
plt.legend()

plt.yticks(xrange(0, len(Groups) * 3, 3), Groups)
plt.ylim(-3, len(Groups)*3)
#plt.xlim(0, 8)
plt.show()

Resulting plot.

结果看起来大部分都像我想要的(据我所知,盒子的范围从第一到第三四分位,因此不可能将其设置为+/-标准偏差)。所以我有点失望没有一线解决方案,但我很高兴有可能。但是,对于数百个团体而言,这还不够好......