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

Matplotlib多图例置于轴外被截断,savefig的bbox_extra_artists参数失效

解决Matplotlib多轴外图例截断问题

我完全懂你遇到的困扰——按照官方文档的方法用add_artist()添加了多个坐标轴外的图例,结果哪怕设置了bbox_extra_artists参数,还是有部分图例被截断,这在处理多图例场景时确实容易踩坑。下面给你几个针对性的解决方案,亲测有效:

核心问题:确保所有图例都被纳入布局计算

很多时候截断的原因是你只把部分图例传入了bbox_extra_artists,Matplotlib默认只会计算坐标轴内的元素,轴外的图例必须全部明确告诉它要考虑尺寸。

示例代码(修正版)

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# 绘制示例曲线
line1, = ax.plot([1,2,3], label='Line 1')
line2, = ax.plot([3,2,1], label='Line 2')
line3, = ax.plot([2,1,3], label='Line 3')
line4, = ax.plot([1,3,2], label='Line 4')

# 创建两个轴外图例
leg1 = ax.legend([line1, line2], ['Line 1', 'Line 2'], loc='upper left', bbox_to_anchor=(1.02, 1))
leg2 = ax.legend([line3, line4], ['Line 3', 'Line 4'], loc='upper left', bbox_to_anchor=(1.02, 0.7))

# 关键:把被覆盖的第一个图例重新添加回坐标轴
ax.add_artist(leg1)

# 重要:将所有图例都传入bbox_extra_artists
# 保存图像时确保包含所有图例
plt.savefig('multi_legend.png', bbox_extra_artists=(leg1, leg2), bbox_inches='tight')

# 如果要在plt.show()时也正常显示,用tight_layout预留空间并传入所有图例
plt.tight_layout(rect=[0, 0, 0.8, 1], extra_artists=(leg1, leg2))
plt.show()

关键细节拆解

  • ax.add_artist(leg1)不能忘:当你创建第二个图例时,Matplotlib会自动移除第一个图例,必须手动把它加回坐标轴,否则第一个图例根本不会显示。
  • bbox_extra_artists要包含所有图例:不管是1个还是N个轴外图例,都要把它们全部放进这个参数的元组里,这样Matplotlib才会计算所有图例的尺寸,调整图像边界。
  • bbox_inches='tight'是保存时的必备项:这个参数会让savefig()根据bbox_extra_artists里的元素自动扩展图像边界,否则哪怕设置了bbox_extra_artists也会截断。
  • tight_layout的rect参数:用rect=[0,0,0.8,1]可以给右侧预留20%的空间放图例,你可以根据图例数量和大小调整这个数值(比如改成0.7预留30%)。

备选方案:用fig.legend()统一管理多图例

如果你的图例数量较多,位置复杂,也可以直接用fig.legend()创建图例,这样不需要手动调用add_artist,布局管理更省心:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

line1, = ax.plot([1,2,3], label='Line 1')
line2, = ax.plot([3,2,1], label='Line 2')
line3, = ax.plot([2,1,3], label='Line 3')
line4, = ax.plot([1,3,2], label='Line 4')

# 直接在画布层面创建多个图例
leg1 = fig.legend([line1, line2], ['Line 1', 'Line 2'], loc='upper left', bbox_to_anchor=(1.02, 1))
leg2 = fig.legend([line3, line4], ['Line 3', 'Line 4'], loc='upper left', bbox_to_anchor=(1.02, 0.7))

# 同样需要把所有图例传入bbox_extra_artists保存
plt.savefig('fig_legend.png', bbox_extra_artists=(leg1, leg2), bbox_inches='tight')
plt.tight_layout(rect=[0,0,0.8,1])
plt.show()

最后一个小技巧

如果调整完还是有轻微截断,可以微调bbox_to_anchor的数值,比如把1.02改成1.05,给图例和坐标轴之间多留一点空隙,避免边缘被裁掉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:05:28