如何将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
相关产品推荐
相关产品推荐

