如何将柱状图改为堆叠图,展示各学科技能的性别占比分层
问题描述
我有一个pandas DataFrame,包含按性别分层的各学科不同技能水平的学生百分比,数据构造代码如下:
iterables = [['Above basic','Basic','Low'], ['Female','Male']] index = pd.MultiIndex.from_product(iterables, names=["Skills", "Gender"]) df = pd.DataFrame(data=[[36,36,8,8,6,6],[46,46,2,3,1,2],[24,26,10,11,16,13]], index=["Math", "Literature", "Physics"], columns=index) print(df)
输出结果为:
Skills Above basic Basic Low Gender Female Male Female Male Female Male Math 36 36 8 8 6 6 Literature 46 46 2 3 1 2 Physics 24 26 10 11 16 13
我已经用以下代码绘制了技能在各学科中的分布柱状图:
# 绘制技能在各学科中的分布柱状图 df.sum(axis=1,level=[0]).plot(kind='bar') df.plot(kind='bar')
现在希望将这些柱状图改为堆叠图,在每个技能类别对应的柱子中按堆叠方式展示男女的占比(例如“Math-Above basic”柱子为50/50,“Literature-Basic”为40/60等),该如何实现?
解决方案
要实现每个技能类别柱子内堆叠男女占比的效果,只需利用pandas绘图的stacked参数,并结合数据的层级结构即可:
方法一:直接利用原DataFrame绘制
pandas支持识别多列层级,直接设置stacked=True就能让同一技能下的男女数据堆叠在同一柱子中,不同技能的柱子并列展示:
import matplotlib.pyplot as plt # 绘制堆叠柱状图 df.plot(kind='bar', stacked=True, figsize=(10, 6)) # 优化图表可读性 plt.title('性别占比按技能水平与学科分布') plt.xlabel('学科') plt.ylabel('百分比') plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 将图例移到图表外侧 plt.tight_layout() plt.show()
方法二:转置数据后分组绘制
如果需要更灵活的控制,可以先转置数据,再按技能层级拆分绘制:
import matplotlib.pyplot as plt # 转置数据,让技能和性别作为行索引,学科作为列 df_transposed = df.T # 按技能层级拆分并绘制堆叠图 df_transposed.unstack(level=1).plot(kind='bar', stacked=True, figsize=(10, 6)) plt.title('性别占比按技能水平与学科分布') plt.xlabel('技能水平') plt.ylabel('百分比') plt.tight_layout() plt.show()
两种方法都能实现需求:每个技能对应的柱子里,男女占比会以堆叠形式展示,比如Math的Above basic柱子会显示Female(36%)和Male(36%)的堆叠效果,Literature的Basic柱子则是Female(2%)和Male(3%)的堆叠。
内容的提问来源于stack exchange,提问作者gabboshow
相关产品推荐
相关产品推荐

