Matplotlib中为3×3子图创建两个底部图例的实现问题
嘿,我刚好碰到过类似的Matplotlib图例问题,给你梳理下解决思路和可行的代码方案!
解决Matplotlib多子图底部双图例问题
你的核心需求是给3×3的多子图添加两个外部底部图例(各对应4条曲线),之前的问题要么图例被裁剪,要么跑到子图内部,关键在于提前预留图例空间+精准控制图例位置。
步骤1:创建子图时预留底部空间
先通过gridspec_kw参数给画布底部留出足够放置两个图例的区域,避免后续图例被裁剪。
import matplotlib.pyplot as plt import numpy as np # 创建3×3子图,底部预留20%的画布空间给图例 fig, axes = plt.subplots(3, 3, figsize=(10, 8), gridspec_kw={'bottom': 0.2}) # 生成8条示例曲线(所有子图曲线样式一致) x = np.linspace(0, 10, 100) curve_objects = [] for i in range(8): y = np.sin(x + i*0.5) # 只在第一个子图绘制并获取曲线对象(后续图例只需要这一组对象) line, = axes[0,0].plot(x, y, label=f'Curve {i+1}') curve_objects.append(line) # 给其他子图复制相同样式的曲线 for ax in axes.flat[1:]: ax.plot(x, y, color=line.get_color(), linestyle=line.get_linestyle())
步骤2:拆分曲线并添加两个底部图例
把8条曲线分成两组,用fig.legend()结合bbox_to_anchor精准控制图例在底部的位置,让它们刚好落在预留的空间里,且不遮挡子图。
# 第一个图例:前4条曲线,放在底部上方12%的位置 fig.legend( curve_objects[:4], [f'Curve {i+1}' for i in range(4)], loc='lower center', ncol=4, title='Legend Group 1', bbox_to_anchor=(0.5, 0.12) # (0.5是水平居中,0.12是垂直距离底部12%) ) # 第二个图例:后4条曲线,放在第一个图例下方 fig.legend( curve_objects[4:], [f'Curve {i+1}' for i in range(4,8)], loc='lower center', ncol=4, title='Legend Group 2', bbox_to_anchor=(0.5, 0.02) ) plt.show()
为什么你之前的代码出问题?
- 用
loc=(0, -0.1)时,图例位置超出了默认画布范围,直接被裁剪了,提前用gridspec_kw预留空间就能解决这个问题。 - 用
loc='lower center'默认是相对于子图区域的中心下方,所以会跑到子图内部,加上bbox_to_anchor就能把图例定位到子图外部的底部区域。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

