多索引 pandas 数据帧中按级别分组的子图

问题描述 投票:0回答:2

如何根据多索引的某一级别从多索引 pandas DataFrame 进行多重绘图?

我得到了在不同场景中使用不同技术的模型的结果,结果可能如下所示:

import numpy as np
import pandas as pd
df=pd.DataFrame(abs(np.random.randn(12,4)),columns=[2011,2012,2013,2014])
df['scenario']=['s1','s1','s1','s2','s2','s3','s3','s3','s3','s4','s4','s4']
df['technology'=['t1','t2','t5','t2','t6','t1','t3','t4','t5','t1','t3','t4']
dfg=df.groupby(['scenario','technology']).sum().transpose()

dfg 每年都会针对每种场景采用技术。我想为每个共享图例的场景都有一个子图。

如果我简单地使用参数 subplots=True,那么它会绘制所有可能的组合(12 个子图)

dfg.plot(kind='bar',stacked=True,subplots=True)

基于此回复,我更接近我正在寻找的东西。

f,a=plt.subplots(2,2)

fig1=dfg['s1'].plot(kind='bar',ax=a[0,0])

fig2=dfg['s2'].plot(kind='bar',ax=a[0,1])

fig2=dfg['s3'].plot(kind='bar',ax=a[1,0])

fig2=dfg['s3'].plot(kind='bar',ax=a[1,1])

plt.tight_layout()

但结果并不理想,每个子图都有不同的图例……这使得阅读起来相当困难。必须有一种更简单的方法来从多索引数据帧中绘制子图......谢谢!

编辑1:Ted Petrou 使用seaborn Factorplot 提出了一个很好的解决方案,但我有两个问题。我已经定义了一个样式,我不想使用seaborn样式(一种解决方案可以是更改seaborn的参数)。另一个问题是我想使用堆积条形图,这需要大量的额外的调整。我有机会用 Matplotlib 做类似的事情吗?

python pandas matplotlib multi-index subplot
2个回答
15
投票

在我看来,当你“整理”数据时,进行数据分析会更容易——使每一列代表一个变量。在这里,所有 4 年都显示在不同的列中。 Pandas 有一种函数和一种方法可以将宽(杂乱)数据变成长(整齐)数据。您可以使用

df.stack
pd.melt(df)
来整理数据。然后您可以利用优秀的seaborn 库,它期望整洁的数据可以轻松绘制您想要的大多数内容。

整理数据

df1 = pd.melt(df, id_vars=['scenario', 'technology'], var_name='year')
print(df1.head())

  scenario technology  year     value
0       s1         t1  2011  0.406830
1       s1         t2  2011  0.495418
2       s1         t5  2011  0.116925
3       s2         t2  2011  0.904891
4       s2         t6  2011  0.525101

使用Seaborn

import seaborn as sns
sns.factorplot(x='year', y='value', hue='technology', 
               col='scenario', data=df1, kind='bar', col_wrap=2,
              sharey=False)


0
投票

实现答案 - Factorplot 函数已重命名为 catplot()。这是Seaborn 文档的链接。

因此你想用它来代替:

sns.catplot(x='year', y='value', hue='technology',
              col='scenario', data=df1, kind='bar', col_wrap=2,
              sharey=False)
© www.soinside.com 2019 - 2024. All rights reserved.