Matplotlib循环绘制多子图时标题与坐标轴标签设置问题求解
问题根因
band_name定义不符合预期:当前写法band_name = ['Sentinel-2 B2'], ['Sentinel-2 B3']会生成仅含2个元素的嵌套元组,长度和6个待绘制的波段组不匹配,循环时每次都将整个band_name对象传入标题设置接口,导致所有子图标题完全相同。- x轴刻度逻辑错误:
set_xticklabels传入的是生成器对象而非实际标签列表,且内部临时变量复用了band_name命名、依赖上层循环残留的row变量计算长度,直接导致刻度显示乱码/异常。 - 波段匹配规则存在隐藏bug:
str.contains默认按正则模式解析匹配字符串,你写的匹配串里的[]是正则特殊字符,会被识别为字符集规则而非字面的方括号,容易匹配到错误的栅格波段列。 - 波段组和标题未做索引绑定,单独用
n变量计数容易出现子图和内容错位,且原代码中band_n最后两项重复、band_name仅定义了2个值,和6个子图的数量不匹配。
修复代码
import matplotlib.pyplot as plt import numpy as np # 按一一对应关系整理波段匹配规则和子图标题,补全缺失项、修正重复的匹配规则 band_n = [ 'Band [2,6,11,16]', 'Band [3,7,12,17]', 'Band [4,8,13,30]', 'Band [20,22,14,26]', 'Band [2,26,11,30]', 'Band [2,26,11,30]' # 若此处为笔误重复,请替换为实际的波段匹配字符串 ] band_name = [ 'Sentinel-2 B2', 'Sentinel-2 B3', 'Sentinel-2 B4', 'Sentinel-2 B8', 'Sentinel-2 B11', 'Sentinel-2 B12' # 请替换为你实际需要的子图标题 ] # 计算各分类对应波段均值 prof = train_pts.groupby(['classes']).mean() fig = plt.figure(figsize=(17,20)) class_names = prof.index.astype(str).tolist() # 初始化色板,保证类别和颜色一一对应 cmap = plt.cm.get_cmap('tab20', len(class_names)) # 同步遍历波段匹配规则、对应标题,用enumerate自动生成子图序号 for plot_idx, (match_str, title) in enumerate(zip(band_n, band_name), start=1): ax = fig.add_subplot(4, 2, plot_idx) ax.set_title(title) # 关闭正则匹配,按字面字符串匹配列,避免特殊字符导致匹配错误 target_cols = prof.columns[prof.columns.str.contains(match_str, regex=False)] band_val = prof[target_cols] # 逐类别绘制均值折线 for class_id, row in band_val.iterrows(): ax.plot(row.values, color=cmap(class_id)) # 修正x轴刻度:先指定刻度位置,再设置标签 x_pos = np.arange(len(target_cols)) ax.set_xticks(x_pos) ax.set_xticklabels([col for col in target_cols], rotation=45, ha='right') # 显式设置坐标轴标签 ax.set_xlabel('Spectral Band') ax.set_ylabel('Mean Reflectance') # 所有曲线绘制完成后再触发自动缩放 ax.autoscale(enable=True, axis='both', tight=True) ax.legend(loc='best', fontsize='small', ncol=2, labels=class_names) # 自动调整子图间距,避免标题、标签重叠 plt.tight_layout() plt.show()
关键改动说明
- 把
band_n和band_name处理为等长列表,通过zip同步遍历绑定,保证每个子图拿到唯一对应的标题,彻底解决标题重复问题。 - 给
str.contains添加regex=False参数,按字面意思匹配列名,避免[]等正则特殊字符导致列匹配错误。 - 重构x轴刻度逻辑:先通过
set_xticks显式指定刻度位置,再传入实际的波段名称作为标签,解决刻度显示异常问题,同时给x轴标签加旋转角度避免文字重叠。 - 移除了单独计数的
n变量,用enumerate自动生成子图序号,避免计数错位。 - 显式添加x、y轴标签,调用
tight_layout()自动调整子图间距,优化整体显示效果。 - 把自动缩放逻辑移到所有曲线绘制完成后执行,避免重复触发导致的视图范围异常。
内容的提问来源于stack exchange,提问作者Gulnihal
相关产品推荐
相关产品推荐

