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
相关产品推荐
相关产品推荐

