You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将柱状图改为堆叠图,展示各学科技能的性别占比分层

问题描述

我有一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:50:44