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

基于DataFrame逐步构建非堆叠柱状图失败,求解决方案

问题:循环绘制非堆叠多系列柱状图失败

我尝试用Pandas、matplotlib和Jupyter构建柱状图,想要同一索引值的多个系列依次排列而非堆叠。写了如下代码:

d = { 
  "shop": [ "London", "Berlin", "Paris" ],
  "sales-2020": [ 1000, 2344, 1233 ],
  "sales-2021": [ 355, 4003, 2344 ],
  "sales-2022": [ 2344, 2949, 3443 ]
}

colors = { "2020": "Blue", "2021": "Green", "2022": "Red" }

df = pd.DataFrame ( d, index = d [ "shop" ] )

ax = None
for yk in [ 2020, 2021, 2022 ]:
  yk = str ( yk )
  ax = df.plot.bar ( y = "sales-" + yk, label = yk, color = colors [ yk ], stacked = False, ax = ax )

但输出有问题:系列始终是堆叠状态,而且第一个系列没显示成柱状图。

注:这是复杂场景的简化,我有9个系列,必须通过循环逐个添加到图表,不能一次性构建;也不需要做透视表,数据已经分组好。


解决方案

问题出在循环调用df.plot.bar()时,每次仅传入单个列,Pandas会默认将这些系列叠加在同一组柱子上,而非并排显示。要实现并排效果,需要手动调整每个系列柱子的位置和宽度。

修改后的代码如下:

import pandas as pd
import matplotlib.pyplot as plt

d = { 
  "shop": [ "London", "Berlin", "Paris" ],
  "sales-2020": [ 1000, 2344, 1233 ],
  "sales-2021": [ 355, 4003, 2344 ],
  "sales-2022": [ 2344, 2949, 3443 ]
}

colors = { "2020": "Blue", "2021": "Green", "2022": "Red" }
years = ["2020", "2021", "2022"]
n_series = len(years)
bar_width = 0.25  # 根据系列数量调整柱子宽度

df = pd.DataFrame(d, index=d["shop"])
x = range(len(df.index))  # 获取x轴位置索引

fig, ax = plt.subplots()

for i, year in enumerate(years):
    # 计算每个系列的x轴偏移量,实现并排效果
    ax.bar([pos + i*bar_width for pos in x], df[f"sales-{year}"], 
           width=bar_width, label=year, color=colors[year])

# 调整x轴刻度位置,使其对齐每组柱子的中间
ax.set_xticks([pos + bar_width*(n_series-1)/2 for pos in x])
ax.set_xticklabels(df.index)
ax.set_xlabel("Shop")
ax.set_ylabel("Sales")
ax.set_title("Sales by Year and Shop")
ax.legend()

plt.show()

关键调整说明

  • 手动计算每个系列的x轴位置偏移,确保同一索引下的柱子并排排列
  • 统一设置柱子宽度,避免重叠
  • 最后调整x轴刻度位置,使其与每组柱子的中心对齐

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:47:34