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

Matplotlib子图散点图图例被覆盖问题求解

子图统一图例生成方案

通过for循环批量生成子图散点图时,若在循环内每次调用plt.legend(),图例会被后续子图覆盖,最终仅显示最后一个子图的图例。需要生成一个涵盖所有年份(2019、2020、2021、2022)的全局统一图例。

解决方案

核心思路是提前生成全局统一的图例元素,循环内仅绘制散点,最后在整个画布上添加一次图例,避免重复覆盖。

修改后的代码:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches

df = pd.read_excel(path)

spp = df.SPP.unique()
# 提前获取所有年份的唯一值,生成全局统一的图例元素
all_years = df['Year'].unique()
all_years.sort()  # 可选:按年份排序保证图例顺序一致
handles = [matplotlib.patches.Patch(color=plt.cm.tab10(i), label=c) for i, c in enumerate(all_years)]

fig, axs = plt.subplots(nrows=8, ncols=4, figsize=(14, 14))

for spp_i, ax in zip(spp, axs.flat):
    df_1 = df[df['SPP'] == spp_i]
    x = df_1['Length_mm']
    y = df_1['Weight_g']
    # 基于全局年份的因子化,确保颜色与图例对应
    levels = df_1['Year'].map(dict(zip(all_years, range(len(all_years)))))
    colors = [plt.cm.tab10(i) for i in levels]
    ax.scatter(x, y, c=colors)
    # 移除循环内的plt.legend()调用

# 在整个画布上添加全局图例,可调整位置参数
fig.legend(handles=handles, loc='upper right', bbox_to_anchor=(1.1, 1), title='Year')

plt.savefig('Test.png', bbox_inches='tight', pad_inches=0.1, dpi=600)

修改说明

  • 提前提取所有年份并生成统一的图例handles,确保所有子图的颜色与图例一一对应。
  • 循环内删除plt.legend()调用,避免每次覆盖图例。
  • 使用fig.legend()替代plt.legend(),将图例绑定到整个画布而非单个子图,通过bbox_to_anchor参数可灵活调整图例位置,避免遮挡子图内容。
  • 对年份进行排序(可选操作),保证图例中年份的顺序符合逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:31:16