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

Python中如何为堆叠条形图的每个等级设置唯一颜色?

为堆叠条形图的每个攀岩等级设置唯一颜色

问题背景

我有一个记录月度攀岩等级分布的DataFrame df:

Grade        4a  4b  4c  5a  5a+  5b  5b+  5c  5c+  6a  6a+  6b  6b+  6c
Month                                                                   
Apr 2024  0   0   0   0   1    2   1    2   7    3  16   12   3    2   0
Aug 2024  0   0   0   0   1    0   2    0   4    5   8    3   1    0   0
Jun 2024  0   0   0   0   0    0   0    0   0    1   4    2   0    1   0
Mar 2024  0   1   0   0   1    0   0    2   3    0   4    0   0    0   0
May 2024  0   0   1   1   1    1   4    1  12    3  20    8   5    1   0

我用以下代码生成100%堆叠条形图,但想给每个等级设置唯一颜色,尝试直接操作bar对象时无法访问单个图例项:

df_norm = df.div(df.sum(axis=1), axis=0)
df_norm.plot(kind="bar", stacked=True, title='Climbing Grades Monthly Progress')
plt.bar(df_norm.columns[1], df_norm.values, "red")  # 这行是无效重复绘制,建议删除
plt.show()

解决方案

方法1:直接在plot时指定颜色映射(最简单)

提前为每个等级定义唯一颜色,传给df.plot()的color参数,pandas会自动将颜色与图例对应:

import matplotlib.pyplot as plt
import pandas as pd

# 假设df已提前定义
df_norm = df.div(df.sum(axis=1), axis=0)

# 生成与等级数量匹配的唯一颜色(用matplotlib配色表,也可手动指定颜色列表)
num_grades = len(df_norm.columns)
colors = plt.cm.tab20.colors[:num_grades]

# 绘制堆叠条形图并指定颜色
ax = df_norm.plot(kind="bar", stacked=True, title='Climbing Grades Monthly Progress', color=colors)

# 调整图例位置避免遮挡图表
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

plt.tight_layout()
plt.show()

方法2:手动修改已绘制的条形颜色

如果已经完成图表绘制,可通过Axes对象的containers属性访问每个等级的条形组,逐个设置颜色并更新图例:

import matplotlib.pyplot as plt
import pandas as pd

df_norm = df.div(df.sum(axis=1), axis=0)
ax = df_norm.plot(kind="bar", stacked=True, title='Climbing Grades Monthly Progress')

# 手动定义每个等级的颜色
colors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A6', '#FFC300', 
          '#8E44AD', '#1ABC9C', '#E74C3C', '#9B59B6', '#3498DB', 
          '#2ECC71', '#F1C40F', '#E67E22', '#95A5A6']

# 遍历每个等级的条形容器,设置颜色并关联图例
for container, color, label in zip(ax.containers, colors, df_norm.columns):
    plt.setp(container, color=color)

# 重新生成完整图例
ax.legend(ax.containers, df_norm.columns, bbox_to_anchor=(1.05, 1), loc='upper left')

plt.tight_layout()
plt.show()

注意事项

  • 原代码中的plt.bar(df_norm.columns[1], df_norm.values, "red")属于无效重复绘制,会干扰现有图表,直接删除即可。
  • 使用plt.tight_layout()可自动调整图表布局,避免标题、图例被截断。

内容的提问来源于stack exchange,提问作者fattyres.co.uk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:40:13