求助:用Python基于Dataframe绘制特定双分类变量堆叠条形图
实现目标堆叠条形图方案
1. 数据预处理(适配你的数据结构)
首先需要计算每个种族/族裔对应的午餐贡献值——即该种族中享受免费/减价午餐的学生占总群体的百分比,公式为:午餐贡献值 = 该分组午餐总百分比 × 种族/族裔占比。
假设你的数据框为df,如果是宽格式(每个种族单独列为一列),处理代码如下:
import pandas as pd import matplotlib.pyplot as plt # 模拟你的数据结构(替换成实际数据即可) data = { "edu_group": ["小学", "初中", "高中"], "White": [0.4, 0.5, 0.6], "Black": [0.3, 0.2, 0.2], "Hispanic": [0.3, 0.3, 0.2], "free_lunch_pct": [65, 58, 45] } df = pd.DataFrame(data) # 计算每个种族的午餐贡献值 race_cols = ["White", "Black", "Hispanic"] for col in race_cols: df[f"{col}_lunch"] = df["free_lunch_pct"] * df[col]
如果是长格式(每行对应一个教育分组+种族的组合),处理代码如下:
# 模拟长格式数据 data = [ {"edu_group": "小学", "race": "White", "race_pct": 0.4, "free_lunch_pct": 65}, {"edu_group": "小学", "race": "Black", "race_pct": 0.3, "free_lunch_pct": 65}, {"edu_group": "小学", "race": "Hispanic", "race_pct": 0.3, "free_lunch_pct": 65}, {"edu_group": "初中", "race": "White", "race_pct": 0.5, "free_lunch_pct": 58}, ] df = pd.DataFrame(data) # 计算贡献值并转成宽格式用于绘图 df["lunch_contribution"] = df["free_lunch_pct"] * df["race_pct"] pivot_df = df.pivot(index="edu_group", columns="race", values="lunch_contribution") race_cols = pivot_df.columns.tolist()
2. 绘制堆叠条形图
# 设置x轴位置与条形宽度 x = range(len(df["edu_group"]) if "edu_group" in df else len(pivot_df.index)) width = 0.7 # 初始化堆叠底部位置 bottom = [0] * len(x) # 遍历种族绘制堆叠块 colors = ["#1f77b4", "#ff7f0e", "#2ca02c"] for idx, race in enumerate(race_cols): # 根据数据格式选择对应的列 values = df[f"{race}_lunch"] if f"{race}_lunch" in df else pivot_df[race] plt.bar(x, values, width, bottom=bottom, label=race, color=colors[idx]) # 更新下一层堆叠的底部位置 bottom = [b + val for b, val in zip(bottom, values)] # 设置轴标签与标题 plt.xticks(x, df["edu_group"] if "edu_group" in df else pivot_df.index) plt.ylabel("享受免费/减价午餐学生百分比") plt.xlabel("教育分组") plt.title("不同教育分组下各族裔午餐福利占比堆叠图") # 添加图例 plt.legend(title="种族/族裔") # 优化布局并显示图表 plt.tight_layout() plt.show()
3. 效果说明
运行代码后会生成你期望的图表:
- X轴为
edu_group(教育分组) - 每个条形总高度对应该分组的午餐福利总百分比
- 条形的堆叠部分对应不同种族/族裔在该午餐福利中的占比
内容的提问来源于stack exchange,提问作者Matthew101
相关产品推荐
相关产品推荐

