Matplotlib:为不同图形分配图例的技术实现问题
解决Matplotlib多子图的图例分配问题
我来帮你搞定这个多图形图例分配的坑!你现在的问题是用了全局的plt.legend(),它只会给当前活跃的轴(Axes)加图例,但你有两个独立的Figure(susc_comp和cole_cole)、三个不同的轴(ax1、ax2、ax3),得给每个轴单独指定图例才行。
核心思路
每个Axes对象(就是你定义的ax1、ax2、ax3)都自带legend()方法,我们要抛弃全局的plt.legend(),转而用每个轴自己的legend()来精准控制图例的归属。
具体实现步骤
1. 循环绘图时收集曲线对象和标签(可选但更灵活)
如果每个温度对应的曲线都要在三个轴上绘制,最好在循环里把每个轴的曲线对象和对应标签存起来,这样后续加图例时能更精准控制:
# 初始化列表存储每个轴的曲线和标签 ax1_plots = [] ax1_labels = [] ax2_plots = [] ax2_labels = [] ax3_plots = [] ax3_labels = [] # 你的循环逻辑 for j, temp in enumerate(indexes_T[i]): # --- 这里是你的数据计算过程 --- # 假设计算后得到x, y1, y2, y3三个轴要用到的数据 # 给ax1绘图,保存曲线对象和标签 line, = ax1.plot(x, y1, label=f"温度 {temp}") ax1_plots.append(line) ax1_labels.append(f"温度 {temp}") # 给ax2绘图 line, = ax2.plot(x, y2, label=f"温度 {temp}") ax2_plots.append(line) ax2_labels.append(f"温度 {temp}") # 给ax3绘图 line, = ax3.plot(x, y3, label=f"温度 {temp}") ax3_plots.append(line) ax3_labels.append(f"温度 {temp}")
2. 分别给每个轴添加图例
循环结束后,针对每个轴调用legend()方法,把之前收集的曲线和标签传进去即可:
# 给ax1加图例 ax1.legend( handles=ax1_plots, labels=ax1_labels, loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), # 转成整数避免浮点数报错 frameon=False ) # 给ax2加图例(参数可复用ax1的逻辑) ax2.legend( handles=ax2_plots, labels=ax2_labels, loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False ) # 给ax3加图例 ax3.legend( handles=ax3_plots, labels=ax3_labels, loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False )
简化版(如果绘图时已指定label)
如果绘图时已经给每个曲线加了label参数,其实可以不用手动收集,直接调用ax.legend()即可,Matplotlib会自动收集当前轴上所有带标签的元素:
# 循环里只需要正常绘图加label for j, temp in enumerate(indexes_T[i]): # 计算数据... ax1.plot(x, y1, label=f"温度 {temp}") ax2.plot(x, y2, label=f"温度 {temp}") ax3.plot(x, y3, label=f"温度 {temp}") # 直接给每个轴加图例 ax1.legend(loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False) ax2.legend(loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False) ax3.legend(loc=0, fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False)
额外小技巧:给整个Figure加共享图例
如果ax1和ax2的图例完全一致(比如都是温度系列),可以给usc_comp这个Figure加一个全局共享图例,放在子图的顶部或底部,让布局更整洁:
# 给susc_comp图加全局图例,放在子图上方 susc_comp.legend( handles=ax1_plots, labels=ax1_labels, loc='upper center', bbox_to_anchor=(0.5, 1.05), # 调整位置到图外 fontsize='small', numpoints=1, ncol=int(len(indexes_T[i])/2), frameon=False )
最后别忘了显示或保存你的图形:
plt.show() # 或者分别保存两个Figure(bbox_inches避免图例被截断) susc_comp.savefig('susc_comp_plot.png', bbox_inches='tight') cole_cole.savefig('cole_cole_plot.png', bbox_inches='tight')
内容的提问来源于stack exchange,提问作者dani reta
相关产品推荐
相关产品推荐

