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

如何将Matplotlib子图的图例放置在绘图区域之外?

解决方案

针对多子图、多曲线图例遮挡数据的问题,以下是几种实用的解决办法:

1. 将图例移到绘图区域外

这是最常用的方案,通过bbox_to_anchor参数指定图例位置,同时调整布局留出空间:

子图独立图例(右侧外)

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 10))

# 绘制多条测试曲线
for i in range(8):
    ax1.plot(x, np.sin(x + i/2), label=f'Curve {i+1}')
    ax2.plot(x, np.cos(x + i/2), label=f'Curve {i+1}')

# 把图例定位到子图右上方外侧
ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0)
ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0)

# 调整右侧边距,避免图例被截断
plt.subplots_adjust(right=0.8)

plt.show()

共享全局图例(更省空间)

如果两个子图的图例条目完全一致,可以只做一个全局图例放在整个图表外侧:

# 绘图部分同上
handles, labels = ax1.get_legend_handles_labels()
# 将图例放在图表右侧中间位置
fig.legend(handles, labels, bbox_to_anchor=(1.05, 0.5), loc='center left', borderaxespad=0)
plt.subplots_adjust(right=0.8)
plt.show()

2. 优化现有图例布局

如果不想移出绘图区,可以通过分栏、缩小字体或增加透明度来减少遮挡:

# 分两栏显示图例,同时缩小字体
ax1.legend(ncol=2, fontsize=8)
ax2.legend(ncol=2, fontsize=8)

# 给图例添加半透明背景,降低遮挡影响
ax1.legend(facecolor='white', alpha=0.8, fontsize=8)

3. 交互式图例(点击切换显示)

实现点击图例条目切换对应曲线的显示/隐藏,适合条目极多的场景:

from matplotlib.legend import Legend

# 绘图部分同上
handles, labels = ax1.get_legend_handles_labels()
legend = ax1.legend(handles, labels)

# 开启图例拾取功能
for handle in legend.get_lines():
    handle.set_picker(True)

# 定义点击事件回调
def on_pick(event):
    line = event.artist
    visible = not line.get_visible()
    line.set_visible(visible)
    # 同步图例条目的透明度,提示状态
    for h in legend.get_lines():
        if h == line:
            h.set_alpha(1.0 if visible else 0.2)
    fig.canvas.draw()

# 绑定事件
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()

4. 单独创建图例子图

把图例作为独立子图放在图表侧边,和绘图区分离:

fig = plt.figure(figsize=(10, 8))
# 布局:2行3列,前两列放两个子图,第三列放图例
ax1 = fig.add_subplot(2, 3, (1,2))
ax2 = fig.add_subplot(2, 3, (4,5))
legend_ax = fig.add_subplot(2, 3, (3,6))

# 绘图部分同上
for i in range(8):
    ax1.plot(x, np.sin(x + i/2), label=f'Curve {i+1}')
    ax2.plot(x, np.cos(x + i/2), label=f'Curve {i+1}')

# 在独立子图中绘制图例
handles, labels = ax1.get_legend_handles_labels()
legend_ax.legend(handles, labels, loc='center')
# 隐藏图例子图的坐标轴
legend_ax.axis('off')

plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:23:38