如何将imshow颜色映射与Matplotlib 3D曲面图的Z轴值关联?
问题描述
我用Matplotlib创建了一个包含两个子图的图形:左侧为3D曲面图,右侧是用imshow绘制的该3D图的2D投影。我期望imshow的颜色映射与3D曲面图关联,但两者刻度不匹配。
我尝试添加了ScalarMappable对象,但颜色映射并未关联到曲面图Z轴(即T矩阵)的数值,颜色条刻度仅显示0到1。请问如何将T矩阵的数值与颜色映射正确关联?
代码如下:
import numpy as np import matplotlib.pyplot as plt id = np.arange(-600,750,150) iq = np.arange(-600,750,150) xx,yy = np.meshgrid(id,iq) T = np.array([[-8988, -8697.5, -7847, -6923, -5610.5, -4536, -3374.35, -2572.85, -1987.65], [-8162, -7910, -7206.5, -6160, -4798.5, -3476.55, -2479.4, -1711.5, -1374.45], [-6513.5, -6814.5, -6398, -5218.5, -3706.5, -2362.15, -1414.7, -1013.6,-883.05], [-4224.5,-4669, -4686.5, -3755.5, -2217.6, -1079.4, -591.85, -313.005,-211.925], [0, 0, 0, 0, 0, 0, 0, 0, 0], [4420.5, 4833.5, 4749.5, 3787, 2221.1, 1054.55, 567.35, 280.42, 146.51], [6793.5, 7017.5, 6510, 5260.5, 3692.5, 2295.3, 1360.45, 914.55, 806.4], [8421, 8008, 7287, 6160, 4725, 3400.25, 2318.4, 1628.2, 1285.55], [9170, 8750, 7864.5, 6874, 5498.5, 4413.5, 3206.7, 2351.3, 1865.5]]) m = plt.cm.ScalarMappable() m.set_array(T) m.set_clim(-9000, 9000) # optional fig = plt.figure(1, figsize=(12,6)) ax = fig.add_subplot(121, projection='3d') ax.set_xlabel(r'$I_d$', fontsize=15) ax.set_ylabel(r'$I_q$', fontsize=15) ax.set_zlabel(r'$T$', fontsize=15) ax.plot_surface(xx, yy, T, cmap=m.cmap, norm = m.norm) ax2 = fig.add_subplot(122) ax2.imshow(T, cmap=m.cmap, norm=m.norm, extent=(np.min(xx), np.max(xx), np.min(yy), np.max(yy)), interpolation=None) cbar = fig.colorbar( plt.cm.ScalarMappable(), ax=ax2 ) plt.tight_layout() plt.show()
当前可视化效果:
解决方案
问题核心是你创建颜色条时,重新实例化了一个全新的ScalarMappable(),而非使用之前已经绑定了T矩阵数值范围的m对象。这个新对象没有关联任何数据,因此颜色条默认显示0-1的刻度。
修改步骤:
- 颜色条直接传入已配置好的
m对象,而非新建ScalarMappable() - 可选:可以用T矩阵的极值自动设置颜色范围,替代手动指定
set_clim,提升灵活性
修改后的完整代码:
import numpy as np import matplotlib.pyplot as plt id = np.arange(-600,750,150) iq = np.arange(-600,750,150) xx,yy = np.meshgrid(id,iq) T = np.array([[-8988, -8697.5, -7847, -6923, -5610.5, -4536, -3374.35, -2572.85, -1987.65], [-8162, -7910, -7206.5, -6160, -4798.5, -3476.55, -2479.4, -1711.5, -1374.45], [-6513.5, -6814.5, -6398, -5218.5, -3706.5, -2362.15, -1414.7, -1013.6,-883.05], [-4224.5,-4669, -4686.5, -3755.5, -2217.6, -1079.4, -591.85, -313.005,-211.925], [0, 0, 0, 0, 0, 0, 0, 0, 0], [4420.5, 4833.5, 4749.5, 3787, 2221.1, 1054.55, 567.35, 280.42, 146.51], [6793.5, 7017.5, 6510, 5260.5, 3692.5, 2295.3, 1360.45, 914.55, 806.4], [8421, 8008, 7287, 6160, 4725, 3400.25, 2318.4, 1628.2, 1285.55], [9170, 8750, 7864.5, 6874, 5498.5, 4413.5, 3206.7, 2351.3, 1865.5]]) # 配置ScalarMappable,绑定T矩阵的数值范围 m = plt.cm.ScalarMappable() m.set_array(T) # 可选:用T的极值自动设置颜色范围,替代手动指定-9000到9000 # m.set_clim(np.min(T), np.max(T)) m.set_clim(-9000, 9000) fig = plt.figure(1, figsize=(12,6)) ax = fig.add_subplot(121, projection='3d') ax.set_xlabel(r'$I_d$', fontsize=15) ax.set_ylabel(r'$I_q$', fontsize=15) ax.set_zlabel(r'$T$', fontsize=15) # 3D曲面图使用已配置的cmap和norm ax.plot_surface(xx, yy, T, cmap=m.cmap, norm=m.norm) ax2 = fig.add_subplot(122) # 2D投影同样使用已配置的cmap和norm ax2.imshow(T, cmap=m.cmap, norm=m.norm, extent=(np.min(xx), np.max(xx), np.min(yy), np.max(yy)), interpolation=None) # 颜色条绑定已配置好的m对象,刻度将匹配T的数值范围 cbar = fig.colorbar(m, ax=ax2) # 为颜色条添加对应T的标签 cbar.set_label(r'$T$', fontsize=15) plt.tight_layout() plt.show()
修改后,颜色条的刻度会正确显示T矩阵的数值范围(-9000到9000),3D曲面图和2D投影的颜色映射会完全一致,实现两者的关联。
内容的提问来源于stack exchange,提问作者sts
相关产品推荐
相关产品推荐

