matplotlib plot_surface绘制整数数组曲面显示异常如何解决
问题根因
两个异常的触发逻辑非常明确:
- 曲面显示单一纯色:matplotlib所有内置colormap的输入值域要求为
[0, 1],直接传入0-5范围的整数数组时,所有大于1的数值都会被colormap截断为上限值对应的纯色,仅值为0的位置会显示最低位颜色,整体视觉上就是单一色块。用np.random.random测试正常是因为该接口生成的浮点值天然落在[0,1]区间,不需要额外映射。整个过程不需要修改原始整数数据,仅在渲染环节做值域适配即可。 - 色条无法关联数据:直接调用
cm.viridis()传入原始数组生成的是固定RGB颜色值列表,没有绑定统一的数值-颜色映射规则,同时plot_surface返回的对象本身不携带全局映射信息,自然无法生成和数据匹配的色条。
修复代码
核心逻辑是先基于整数数据的全局取值范围创建统一归一化规则,再用同一个可映射对象生成三个曲面的颜色、绑定色条,全程不修改原始整数数组:
import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt from matplotlib.cm import ScalarMappable # 保留原始三维整数数组,不做任何修改 data = np.random.randint(0, 6, size=(49, 512, 512)) # 取数据全局最值作为颜色映射的上下限 vmin, vmax = data.min(), data.max() # 构建归一化规则:仅用于渲染时把原始值映射到colormap要求的[0,1]区间 norm = plt.Normalize(vmin=vmin, vmax=vmax) x = y = np.arange(0, 512, 1) z, z1, z2 = 20, 21, 22 i, i1, i2 = data[z,:,:], data[z1,:,:], data[z2,:,:] X, Y = np.meshgrid(x, y) Z = z * np.ones(X.shape) Z1 = z1 * np.ones(X.shape) Z2 = z2 * np.ones(X.shape) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.view_init(10, 60) # 三个曲面使用同一套映射规则生成面颜色 ax.plot_surface(X, Y, Z, facecolors=cm.viridis(norm(i))) ax.plot_surface(X, Y, Z1, facecolors=cm.viridis(norm(i1))) ax.plot_surface(X, Y, Z2, facecolors=cm.viridis(norm(i2))) # 构建统一的标量映射对象,绑定色条即可同时关联三个曲面的色阶 sm = ScalarMappable(norm=norm, cmap=cm.viridis) sm.set_array([]) # 修复3D场景下色条维度报错问题 fig.colorbar(sm, ax=ax, shrink=0.7) plt.show()
效果说明
- 原始整数数组完全保留,没有做任何归一化改写
- 三个曲面的颜色严格对应原始整数值,相同数值在不同曲面上显示颜色完全一致
- 色条刻度自动匹配原始整数范围,可直接对照读取任意曲面位置的原始数值
内容的提问来源于stack exchange,提问作者T Walker
相关产品推荐
相关产品推荐

