如何以熊猫方式绘制堆叠条形图?
Posted
技术标签:
【中文标题】如何以熊猫方式绘制堆叠条形图?【英文标题】:How to plot stacked bar-charts in pandastic way? 【发布时间】:2020-02-04 16:24:17 【问题描述】:我的数据框主要包含分类列:
df = pd.DataFrame(
'col_to_group': ['A', 'A', 'B', 'B', 'A'],
'col_1': ['a', 'b', 'c', 'a', 'a'],
'col_2': ['x', 'y', 'y', 'y','x'],
'col_3': [.1, .2, .1, .9, .7]
)
基本上,我想为col_1
、col_2
按来自col_to_group
(A、B)的子组和整个数据框(ALL)绘制条形图。
这是我目前的解决方案:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(
'col_to_group': ['A', 'A', 'B', 'B', 'A'],
'col_1': ['a', 'b', 'c', 'a', 'a'],
'col_2': ['x', 'y', 'y', 'y','x'],
'col_3': [.1, .2, .1, .9, .7]
)
for i in ['col_1', 'col_2']:
L = df.groupby('col_to_group')[i].value_counts(normalize=True).unstack().T
R = df[i].value_counts(normalize=True).rename('ALL')
z = pd.concat([L, R], axis=1, sort=True).T
#z.T.to_csv(i+'_bar.csv')
#plotting:
zz = z.plot.bar(stacked=True).legend(bbox_to_anchor=(1.0, 1.0)).get_figure()
plt.title(i, fontsize = 12)
zz.savefig(i+'_bar.png', dpi=300, bbox_inches='tight')
plt.show()
z
的创作很复杂,我也不是matplotlib
的粉丝 - 可以一行完成吗?
我正在为此寻找熊猫解决方案。
【问题讨论】:
pandastic
这个词简直荒谬。我希望这永远不会赶上。
但是,说真的,您能提供一张您预期输出的图片吗?
@adrianp 问题描述中的片段会生成预期的图表。 Pandastic,类似于 pythonic,但适用于 pandas ;)
【参考方案1】:
深入研究文档后,我发现crosstab
与margins
和normalize=index
更巧妙地解决了我的问题。
import pandas as pd
df = pd.DataFrame(
'col_to_group': ['A', 'A', 'B', 'B', 'A'],
'col_1': ['a', 'b', 'c', 'a', 'a'],
'col_2': ['x', 'y', 'y', 'y','x'],
'col_3': [.1, .2, .1, .9, .7]
)
for i in ['col_1', 'col_2']:
(pd.crosstab(df['col_to_group'], df[i], margins=True, margins_name='ALL', normalize='index')
.plot.bar(stacked=True).legend(title=i, bbox_to_anchor=(1.0, 1.0)).get_figure()
.savefig(i + '_bar.png', dpi=300, bbox_inches='tight')
)
【讨论】:
【参考方案2】:我会这样做:
df1=df.groupby('col_to_group')['col_1','col_2'].apply(lambda x: x.apply(lambda x: x.value_counts(normalize=True),axis=0)).unstack(level=1).dropna(how='all',axis=1).fillna(0)
print(df1)
col_1 col_2
a b c x y
col_to_group
A 0.666667 0.333333 0.0 0.666667 0.333333
B 0.500000 0.000000 0.5 0.000000 1.000000
df2=df[['col_1','col_2']].apply(lambda x: x.value_counts(normalize=True)).unstack().dropna().rename('ALL').to_frame().T
print(df2)
col_1 col_2
a b c x y
ALL 0.6 0.2 0.2 0.4 0.6
plot_df=pd.concat([df1,df2])
print(plot_df)
col_1 col_2
a b c x y
A 0.666667 0.333333 0.0 0.666667 0.333333
B 0.500000 0.000000 0.5 0.000000 1.000000
ALL 0.600000 0.200000 0.2 0.400000 0.600000
plot_df['col_1'].plot(kind='bar',stacked=True)
plot_df['col_2'].plot(kind='bar',stacked=True)
【讨论】:
谢谢。我发现crosstab
解决了我的问题。
现在,我想如何将您的想法结合到一个数据框中并使用子图来消除循环。以上是关于如何以熊猫方式绘制堆叠条形图?的主要内容,如果未能解决你的问题,请参考以下文章