如何为Matplotlib切片子图设置匹配原数组的Y轴刻度?
解决Matplotlib子图Y轴显示原数组真实索引的问题
问题分析
使用matshow绘制数组切片子图时,Y轴默认显示切片后的局部索引(从0开始),但你需要让每个子图的Y轴对应原数组的真实起始索引(如第二个子图从100开始、间隔20)。之前的尝试没达到效果,是因为没做好局部刻度位置与真实索引的映射。
解决方案
核心思路:保留matshow自动生成的Y轴刻度位置,将这些位置对应的局部索引加上子图切片的起始偏移量,替换为真实索引标签。
修改后的完整代码:
import matplotlib.pyplot as plt import numpy as np # 替换为你的真实q_func数组 q_func = np.random.rand(500, 6) fig, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 5, figsize=(6,12), layout='constrained', sharex=True) min_val = q_func.min() max_val = q_func.max() plt.rcParams.update({"text.usetex": True,"font.family": "Computer Modern Serif"}) # 绘制子图并记录每个子图对应的原数组起始索引 ax1.matshow(q_func[0:99,:], vmin=min_val, vmax=max_val, aspect='equal', cmap='viridis') ax2.matshow(q_func[100:199,:], vmin=min_val, vmax=max_val, aspect='equal', cmap='viridis') ax3.matshow(q_func[200:299,:], vmin=min_val, vmax=max_val, aspect='equal', cmap='viridis') ax4.matshow(q_func[300:399,:], vmin=min_val, vmax=max_val, aspect='equal', cmap='viridis') im = ax5.matshow(q_func[400:499,:], vmin=min_val, vmax=max_val, aspect='equal', cmap='viridis') # 批量设置Y轴真实索引标签 def update_yticks(ax, start_idx): # 获取当前子图的局部刻度值 local_ticks = ax.get_yticks() # 转换为原数组真实索引 real_ticks = [int(tick) + start_idx for tick in local_ticks] ax.set_yticklabels(real_ticks) update_yticks(ax1, 0) update_yticks(ax2, 100) update_yticks(ax3, 200) update_yticks(ax4, 300) update_yticks(ax5, 400) # 固定间隔刻度的自定义方式(以ax2为例) # local_ticks = np.arange(0, 100, 20) # ax2.set_yticks(local_ticks) # ax2.set_yticklabels(local_ticks + 100) fig.supxlabel("Acciones") fig.supylabel("Estados") fig.suptitle("$Q$-función aproximada con 2000 episodios") fig.colorbar(im) plt.show()
关键说明
- 封装的
update_yticks函数:复用逻辑,避免重复代码,利用子图自动生成的刻度位置,确保标签与刻度位置精准对应。 - 自定义间隔刻度:如果需要固定间隔(比如间隔20),可以手动指定局部刻度位置,再转换为真实索引,注释中的代码可直接使用。
内容的提问来源于stack exchange,提问作者oso_hormiguero
相关产品推荐
相关产品推荐

