Boxplot与multiindex

时间:2017-10-06 10:35:43

标签: python python-3.x pandas matplotlib seaborn

假设我有一个Dataframe,其列为Multiindex。例如:

a = pd.DataFrame(index=range(10), 
                 columns=pd.MultiIndex.from_product(
                         iterables=[['2000', '2010'], ['a', 'b']], 
                         names=['Year', 'Text']), 
                 data=np.random.randn(10,4))

我想制作一个按年份分组的箱线图。就像seaborn boxplots上的hue arg一样。 我想知道是否有一种简单的方法可以在pandas / seaborn / matplotlib中实现这一目标。 我觉得一个卸载可以做到这一点,但我无法让它发挥作用。

1 个答案:

答案 0 :(得分:5)

使用stack进行重塑并按DataFrame.boxplot绘制

np.random.seed(45)
a = pd.DataFrame(index=range(10), 
                 columns=pd.MultiIndex.from_product(
                         iterables=[['2000', '2010'], ['a', 'b']], 
                         names=['Year', 'Text']), 
                 data=np.random.randn(10,4))

b = a.stack(level=0).reset_index(level=0, drop=True).reset_index()
print (b)
Text  Year         a         b
0     2000  0.026375  0.260322
1     2010 -0.395146 -0.204301
2     2000 -1.271633 -2.596879
3     2010  0.289681 -0.873305
4     2000  0.394073  0.935106
5     2010 -0.015685  0.259596
6     2000 -1.473314  0.801927
7     2010 -1.750752 -0.495052
8     2000 -1.008601  0.025244
9     2010 -0.121507 -1.546873
10    2000 -0.606944 -1.393813
11    2010 -0.627695  0.332632
12    2000 -1.541367  1.670300
13    2010 -0.499546  0.673129
14    2000  2.248090 -1.654263
15    2010 -0.474397 -0.301915
16    2000 -0.931026  1.110986
17    2010 -0.189683  1.278410
18    2000 -0.554077  0.354303
19    2010 -0.440276 -0.424449
b.boxplot(by='Year')

graph

使用seaborn boxplotunstack解决方案:

b = a.unstack(level=0).reset_index(level=2, drop=True).reset_index(name='data')
print (b.head(15))
    Year Text      data
0   2000    a  0.026375
1   2000    a -1.271633
2   2000    a  0.394073
3   2000    a -1.473314
4   2000    a -1.008601
5   2000    a -0.606944
6   2000    a -1.541367
7   2000    a  2.248090
8   2000    a -0.931026
9   2000    a -0.554077
10  2000    b  0.260322
11  2000    b -2.596879
12  2000    b  0.935106
13  2000    b  0.801927
14  2000    b  0.025244


ax = sns.boxplot(x='Text', y='data', hue="Year",
                 data=b, palette="Set3")

graph1