Matplotlib分组柱状图配色:实现A组统一色、B组分色带独立图例
Matplotlib 分组柱状图定制实现方案
核心原理
Matplotlib 的 bar() 方法会返回所有生成柱状条的对象容器,默认给整组柱状条传统一颜色参数,本质是批量给容器内的每个柱状条实例赋值颜色。只要拿到B组的柱状条实例列表,就可以按索引单独修改每根条的填充色,完全不需要复杂的封装逻辑。
分步实现步骤
- 初始化画布与坐标轴,计算分组柱状图的x轴偏移位置,保留
bar()方法的返回对象 - 遍历A组所有柱状条实例,批量设置统一的填充色,满足A组全条同色的要求
- 提前准备和B组柱状条数量一一对应的自定义配色列表,遍历B组的柱状条实例,按索引给每根条匹配对应的差异化颜色
- 手动构建图例元素:A组用统一颜色生成1个图例项,B组每根不同颜色的柱子单独生成1个图例项,拼合后把图例放到画布侧边位置,避免遮挡主图
可直接运行的完整示例代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Patch # 测试数据准备 indicator_labels = ["营收", "用户量", "留存率", "转化率"] a_group_data = [23, 45, 32, 51] b_group_data = [18, 39, 42, 27] bar_width = 0.35 x_pos = np.arange(len(indicator_labels)) # 初始化画布 fig, ax = plt.subplots(figsize=(8, 5)) # 绘制两组柱状图,保留返回的bar实例 bars_a = ax.bar(x_pos - bar_width/2, a_group_data, width=bar_width) bars_b = ax.bar(x_pos + bar_width/2, b_group_data, width=bar_width) # 给A组设置统一配色 a_color = "#34495e" for bar in bars_a: bar.set_facecolor(a_color) bar.set_edgecolor("white") # 可选:加白边让组间区分更明显 # 给B组设置差异化配色 b_colors = ["#e74c3c", "#f39c12", "#2ecc71", "#9b59b6"] for idx, bar in enumerate(bars_b): bar.set_facecolor(b_colors[idx]) bar.set_edgecolor("white") # 手动构建图例 legend_items = [ Patch(facecolor=a_color, label="A组") ] b_legend_labels = ["B组-营收", "B组-用户量", "B组-留存率", "B组-转化率"] for idx, color in enumerate(b_colors): legend_items.append(Patch(facecolor=color, label=b_legend_labels[idx])) # 把图例放到画布外侧 ax.legend(handles=legend_items, bbox_to_anchor=(1.03, 1), loc="upper left") # 基础图表样式配置 ax.set_xticks(x_pos) ax.set_xticklabels(indicator_labels) ax.set_ylabel("指标数值") ax.set_title("A/B组指标对比") fig.tight_layout() # 自动调整布局防止图例被裁剪 plt.show()
容易踩的坑
- B组柱子初始化时不要提前传统一的
color参数,后续单独修改时容易出现填充色和边框色不匹配的问题,初始化时不传颜色、后续单独赋值的稳定性最高 - B组自定义配色列表的长度必须和B组柱子的数量完全一致,否则会触发索引越界报错
- 不要给B组的柱子设置统一的
label参数,否则手动构建图例时会出现重复的图例项
内容的提问来源于stack exchange,提问作者Unknown Shin
相关产品推荐
相关产品推荐

