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

如何合并Matplotlib柱状图图例中的重复标签?

解决Matplotlib图例重复显示问题

问题背景

从PostgreSQL获取包含(ID, Object, Percentage, Color)的数据集后,使用Matplotlib绘制柱状图时,图例中相同颜色(如Red)的标签重复出现。

测试数据

result = [
    (1, 'Apple', 10, 'Red'),
    (2, 'Blueberry', 40, 'Blue'),
    (3, 'Cherry', 94, 'Red'), 
    (4, 'Orange', 68, 'Orange')
]

原始绘图代码

import pandas as pd
from matplotlib import pyplot as plt
import psycopg2
conn = psycopg2.connect(
    host="localhost",
    port="5432",
    database="db",
    user="user",
    password="123")
cur = conn.cursor()
cur.callproc("test_stored_procedure")
result = cur.fetchall()
cur.close()
conn.close()
print(result)

result = pd.DataFrame(result, columns=['ID', 'Object', 'Percentage', 'Color'])
fruits = result.Object
counts = result.Percentage
labels = result.Color
s = 'tab:'
bar_colors = [s + x for x in result.Color]

fig, ax = plt.subplots()

for x, y, c, lb in zip(fruits, counts, bar_colors, labels):
    ax.bar(x, y, color=c, label=lb)

ax.set_ylabel('fruit supply')
ax.set_title('Fruit supply by kind and color')
ax.legend(title='Fruit color', loc='upper left')

plt.show()

问题现象

图表图例中,Red标签重复显示两次,不符合“每种颜色仅显示一次图例”的需求。

原因分析

原始代码在循环绘制每个柱状条时,都会为当前条目的颜色添加一次label参数。当多个条目颜色相同时,就会生成多个相同的图例标签,最终导致重复显示。

解决方案

方法1:手动去重图例条目

提取图例的手柄(handles)和标签(labels),利用字典的唯一性去重后重新生成图例:

# 保留原始绘图逻辑,仅修改图例部分
fig, ax = plt.subplots()

for x, y, c, lb in zip(fruits, counts, bar_colors, labels):
    ax.bar(x, y, color=c, label=lb)

ax.set_ylabel('fruit supply')
ax.set_title('Fruit supply by kind and color')

# 新增去重逻辑
handles, labels = ax.get_legend_handles_labels()
# 字典自动去重,保留最后一个出现的条目(需保留第一个可反转后再转回)
unique_legend = dict(zip(labels, handles))
ax.legend(unique_legend.values(), unique_legend.keys(), title='Fruit color', loc='upper left')

plt.show()

方法2:按颜色分组绘制

利用Pandas的groupby按颜色分组,每组仅添加一次标签,从根源避免重复:

result = pd.DataFrame(result, columns=['ID', 'Object', 'Percentage', 'Color'])

fig, ax = plt.subplots()

# 按颜色分组绘制,每组仅添加一次标签
for color, group in result.groupby('Color'):
    ax.bar(group['Object'], group['Percentage'], color=f'tab:{color}', label=color)

ax.set_ylabel('fruit supply')
ax.set_title('Fruit supply by kind and color')
ax.legend(title='Fruit color', loc='upper left')

plt.show()

方法3:循环时仅首次添加标签

在循环过程中记录已添加过的颜色,仅为每种颜色的第一个柱状条添加标签:

result = pd.DataFrame(result, columns=['ID', 'Object', 'Percentage', 'Color'])
fruits = result.Object
counts = result.Percentage
labels = result.Color
s = 'tab:'
bar_colors = [s + x for x in result.Color]

fig, ax = plt.subplots()

seen_colors = set()
for x, y, c, lb in zip(fruits, counts, bar_colors, labels):
    # 仅首次遇到该颜色时设置label,后续条目不设置
    current_label = lb if lb not in seen_colors else None
    ax.bar(x, y, color=c, label=current_label)
    seen_colors.add(lb)

ax.set_ylabel('fruit supply')
ax.set_title('Fruit supply by kind and color')
ax.legend(title='Fruit color', loc='upper left')

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:47:23