如何用imshow()实现反转对数Y轴的频谱图绘制?
解决imshow实现反转对数Y轴的频谱图问题
我明白你想要用imshow()实现和pcolormesh()一样的反转对数Y轴效果——毕竟imshow()的渲染效率确实更高。你之前尝试的origin参数和invert_yaxis()没达到预期,问题出在这两个设置的组合方式上,咱们来一步步解决:
问题根源
imshow()的origin参数决定了数据行与extent中Y范围的对应关系,而对数轴的刻度变换会影响最终的显示顺序。之前的组合没让数据行和反转后的对数轴正确匹配,导致显示效果和预期不符。
正确解决方案
要实现和pcolormesh()一致的效果,需要将origin='upper'和invert_yaxis()配合使用,具体步骤:
- 先设置Y轴为对数刻度;
- 调用
imshow()时指定origin='upper',让数据的第一行对应extent中Y的最大值(大周期),最后一行对应Y的最小值(小周期); - 最后调用
invert_yaxis()反转Y轴,让大周期值显示在轴的底部,小周期值显示在顶部。
修改后的可复现代码
import matplotlib.pyplot as plt import numpy as np size = 10 data = np.arange(size * size).reshape((size, size)) x_start = 1 x_end = 10 y_start = 1 y_end = 10 extent = [x_start, x_end, y_start, y_end] fig, axes = plt.subplots(1,5) # 原错误示例1 axes[0].set_yscale('log') im = axes[0].imshow(data, extent=extent, origin='upper', interpolation='None', cmap='viridis') axes[0].set_title("not ok") # 原错误示例2 axes[1].set_yscale('log') im2 = axes[1].imshow(data, extent=extent, origin='lower', interpolation='None', cmap='viridis') axes[1].set_title("not ok") # 原错误示例3 axes[2].set_yscale('log') im2 = axes[2].imshow(data, extent=extent, origin='lower', interpolation='None', cmap='viridis') axes[2].invert_yaxis() axes[2].set_title("not ok") # 正确示例 axes[3].set_yscale('log') im4 = axes[3].imshow(data, extent=extent, origin='upper', interpolation='None', cmap='viridis') axes[3].invert_yaxis() axes[3].set_title("OK (imshow)") # 原pcolormesh参考(修正x的长度匹配pcolormesh要求) y = np.arange(1,11)*0.1 x = np.arange(0,11) axes[4].set_yscale('log') im3 = axes[4].pcolormesh(x, 1/y , data) axes[4].set_title("OK (pcolormesh)") plt.tight_layout() plt.show()
为什么这样有效
origin='upper':让数据的第一行对应extent中Y的最大值(10,大周期),最后一行对应Y的最小值(1,小周期);invert_yaxis():反转对数Y轴的显示顺序,原本顶部的10会移到轴的底部,底部的1移到顶部,刚好让数据的第一行(大周期)显示在轴的底部,和pcolormesh()的效果完全一致。
内容的提问来源于stack exchange,提问作者n0n0bstan
相关产品推荐
相关产品推荐

