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

如何用循环实现DataFrame多列堆叠百分比柱状图的绘制?

问题描述

已手动实现DataFrame的堆叠百分比柱状图,代码如下:

#creating a dataframe
r = [0,1,2,3,4]
raw_data = {'greenBars': [20, 1.5, 7, 10, 5], 'orangeBars': [5, 15, 5, 10, 15],'blueBars': [2, 15, 18, 5, 10]}
df = pd.DataFrame(raw_data)

# From raw value to percentage
totals = list(df.sum(axis=1))
greenBars = [i / j * 100 for i,j in zip(df['greenBars'], totals)]
orangeBars = [i / j * 100 for i,j in zip(df['orangeBars'], totals)]
blueBars = [i / j * 100 for i,j in zip(df['blueBars'], totals)]
 
# plot
barWidth = 0.85
names = ('A','B','C','D','E')
# Create green Bars
plt.bar(df.index, greenBars, color='#b5ffb9', edgecolor='white', width=barWidth, label="group A")
# Create orange Bars
plt.bar(r, orangeBars, bottom=greenBars, color='#f9bc86', edgecolor='white', width=barWidth, label="group B")
# Create blue Bars
plt.bar(r, blueBars, bottom=[i+j for i,j in zip(greenBars, orangeBars)], color='#a3acff', edgecolor='white', width=barWidth, label="group C")
 
# Custom x axis
plt.xticks(r, names)
plt.xlabel("group")

# Add a legend
plt.legend(loc='upper left', bbox_to_anchor=(1,1), ncol=1)

# Show graphic
plt.show()

但尝试用循环批量绘制多列DataFrame时,仅第一列柱状图完整显示,其余列显示不全,循环代码如下:

#Same df as above
for column in df:
  placeholder = [i / j * 100 for i,j in zip(df[column], totals)]
  print(f'placeholder of {column}')
  print(placeholder)
  barWidth = 0.85
  names = ('A','B','C','D','E')
  # Create green Bars
  plt.bar(df.index, placeholder, edgecolor='Black', width=barWidth, label = f"{column}")
修复方案

原循环代码的核心问题是未处理堆叠柱状图的bottom参数,每一列都从Y轴0位置开始绘制,后续列会和前面的列重叠,导致显示不全。同时重复定义无关变量也会降低效率,修复步骤如下:

  1. 提前计算每行总和、定义统一的图表参数(如barWidth、X轴名称),避免循环内重复执行
  2. 初始化一个全0的列表bottom,用于记录每一行当前堆叠的总高度
  3. 循环遍历每一列时,将bottom传入plt.bar()的bottom参数,让当前列从之前堆叠的高度开始绘制
  4. 绘制完成后,更新bottom为当前堆叠高度加上列高度,供下一列使用
  5. 将X轴自定义、图例添加、图表显示等操作放在循环外,确保只执行一次

修复后的完整代码:

import pandas as pd
import matplotlib.pyplot as plt

# 创建DataFrame
r = [0,1,2,3,4]
raw_data = {'greenBars': [20, 1.5, 7, 10, 5], 'orangeBars': [5, 15, 5, 10, 15],'blueBars': [2, 15, 18, 5, 10]}
df = pd.DataFrame(raw_data)

# 计算每行总和,用于转换为百分比
totals = list(df.sum(axis=1))
# 统一图表参数
barWidth = 0.85
names = ('A','B','C','D','E')
# 初始化堆叠底部,初始为0
bottom = [0] * len(df)

for column in df:
    # 计算当前列的百分比
    placeholder = [i / j * 100 for i,j in zip(df[column], totals)]
    # 绘制当前列,指定bottom参数实现堆叠
    plt.bar(df.index, placeholder, edgecolor='Black', width=barWidth, label=column, bottom=bottom)
    # 更新堆叠底部,累加当前列高度
    bottom = [current_bottom + p for current_bottom, p in zip(bottom, placeholder)]

# 自定义X轴
plt.xticks(r, names)
plt.xlabel("group")

# 添加图例
plt.legend(loc='upper left', bbox_to_anchor=(1,1), ncol=1)

# 显示图表
plt.show()

内容的提问来源于stack exchange,提问作者0k4y

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:07:03