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

请求修复Matplotlib堆叠条形图图例:每个灾害类型仅显示一次

修复堆叠条形图重复图例问题

我需要帮助修复图表图例。在某一可视化中图例显示正常,但当前的堆叠条形图中,每个灾害类型对应多个颜色,图例重复显示。我希望每个灾害类型在图例中仅出现一次。已尝试使用colormap和颜色列表,但结果相同,期望实现图例中每个灾害类型仅显示一次的效果。

用户提供的原始代码:

continent_filter = widgets.SelectMultiple(
    options=['Africa', 'Americas', 'Asia', 'Europe', 'Oceania'],
    value=[pivot_df.columns.get_level_values(0).unique()[0]],
    description='Continent',
    disabled=False
)
colors = ['red', 'green', 'blue', 'orange', 'purple', 'yellow', 'cyan', 'magenta', 'lime', 'pink', 'teal', 'brown', 'gray', 'olive', 'navy']

def update_plot(continent):
    ax = pivot_df[continent].plot(kind="bar", stacked=True, color= colors, figsize=(15, 6))
    plt.xlabel('Year')
    plt.ylabel('Number of Events')
    plt.title('Number of Events by Year, Continent, and Disaster Type')
    plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
    xtick_labels = [label.get_text().split('-')[0] for label in ax.get_xticklabels()]
    ax.set_xticklabels(xtick_labels)
    plt.xticks(rotation=45)
    plt.show()

widgets.interact(update_plot, continent=continent_filter)

解决方案

问题根源在于pivot_df的列是多级索引(大陆+灾害类型),调用plot()时会为每个子列生成图例项,导致同一灾害类型重复出现。以下是修复步骤:

1. 创建灾害类型-颜色映射

确保同一灾害类型始终对应相同颜色,避免视觉混乱:

# 获取所有唯一的灾害类型
disaster_types = pivot_df.columns.get_level_values(1).unique()
# 创建灾害类型与颜色的映射字典
color_map = dict(zip(disaster_types, colors[:len(disaster_types)]))

2. 修改绘图函数,去重图例

在绘图后提取图例的手柄(handle)和标签(label),过滤重复的灾害类型,仅保留每个类型的第一个实例:

修改后的完整代码:

continent_filter = widgets.SelectMultiple(
    options=['Africa', 'Americas', 'Asia', 'Europe', 'Oceania'],
    value=[pivot_df.columns.get_level_values(0).unique()[0]],
    description='Continent',
    disabled=False
)
colors = ['red', 'green', 'blue', 'orange', 'purple', 'yellow', 'cyan', 'magenta', 'lime', 'pink', 'teal', 'brown', 'gray', 'olive', 'navy']

# 预创建灾害类型-颜色映射
disaster_types = pivot_df.columns.get_level_values(1).unique()
color_map = dict(zip(disaster_types, colors[:len(disaster_types)]))

def update_plot(continent):
    ax = pivot_df[continent].plot(kind="bar", stacked=True, color=color_map, figsize=(15, 6))
    plt.xlabel('Year')
    plt.ylabel('Number of Events')
    plt.title('Number of Events by Year, Continent, and Disaster Type')
    
    # 提取图例并去重
    handles, labels = ax.get_legend_handles_labels()
    seen = set()
    new_handles = []
    new_labels = []
    for h, l in zip(handles, labels):
        # 从多级索引标签中提取灾害类型(l是元组,格式为(大陆, 灾害类型))
        disaster_type = l[1]
        if disaster_type not in seen:
            seen.add(disaster_type)
            new_handles.append(h)
            new_labels.append(disaster_type)
    
    # 使用去重后的图例
    plt.legend(new_handles, new_labels, bbox_to_anchor=(1.05, 1), loc='upper left')
    
    xtick_labels = [label.get_text().split('-')[0] for label in ax.get_xticklabels()]
    ax.set_xticklabels(xtick_labels)
    plt.xticks(rotation=45)
    plt.show()

widgets.interact(update_plot, continent=continent_filter)

说明

  • 颜色映射color_map确保同一灾害类型在不同大陆的图表中颜色一致;
  • 图例去重逻辑通过遍历所有图例项,记录已出现的灾害类型,仅保留首次出现的手柄和标签,最终生成唯一的灾害类型图例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:03:12