如何为Matplotlib子图设置子标题并按行统一Y轴刻度?
问题解决与代码修改
问题1:function2的suptitle未显示
原因:一个Matplotlib Figure对象只能有一个全局超级标题(suptitle),两次调用plt.suptitle()会导致后设置的覆盖前一个,且你实际需要的是每行子图有独立的行标题,而非全局单一标题。
解决方式:
- 移除函数内部的
plt.suptitle()调用,转而在外部为每行子图添加独立标题,或按需设置全局标题。 - 用
fig.text()精准定位行标题,确保每行的标题清晰独立。
问题2:全局统一Y轴不符合按行统一需求
原因:plt.subplots(sharey=True)会让所有子图共享同一Y轴,而需求是每行内部的子图共享Y轴,两行之间不共享。
解决方式:
- 将
sharey参数设置为'row',即可实现按行共享Y轴。
修改后的完整代码
import matplotlib.pyplot as plt import seaborn as sns import numpy as np # 假设df_train为已加载的数据集 list_soal = ['SalePrice', 'GrLivArea', 'GarageArea'] def function1(ax): for i in range(len(list_soal)): sns.histplot(df_train[list_soal[i]], kde=False, stat='density', bins=30, ax=ax[i]) sns.kdeplot(df_train[list_soal[i]], ax=ax[i]) ax[i].set_xlabel(list_soal[i]) def function2(ax): for i in range(len(list_soal)): transformed_data = np.log10(df_train[list_soal[i]]) sns.histplot(transformed_data, kde=False, stat='density', bins=30, ax=ax[i]) sns.kdeplot(transformed_data, ax=ax[i]) ax[i].set_xlabel(f'log10({list_soal[i]})') # 创建2行3列子图,按行共享Y轴 fig, ax = plt.subplots(2, 3, figsize=(20, 8), sharey='row') # 调用绘图函数 function1(ax[0]) function2(ax[1]) # 添加每行的独立标题 fig.text(0.5, 0.95, 'Histogram for Non-Transformed Data', ha='center', fontsize=14, weight='bold') fig.text(0.5, 0.48, 'Histogram for Transformed Data (log10)', ha='center', fontsize=14, weight='bold') # 调整布局,避免标题与子图重叠 plt.tight_layout(rect=[0, 0, 1, 0.93]) plt.show()
关键修改点说明
- 按行共享Y轴:将
sharey=True改为sharey='row',实现每行内部子图共享Y轴,两行Y轴独立显示。 - 修复标题显示:
- 删除函数内重复的
plt.suptitle()调用,改用fig.text()为每行添加专属标题,通过ha='center'居中,y参数控制垂直位置。 - 用
plt.tight_layout(rect=[0,0,1,0.93])调整子图间距,避免标题与子图重叠。
- 删除函数内重复的
- 优化可读性:为每个子图添加X轴标签,明确展示对应的数据字段。
内容的提问来源于stack exchange,提问作者lokalhangatt
相关产品推荐
相关产品推荐

