如何在坐标轴中绘制多个采用不同colormap的曲面?
给单个曲面设置独立配色方案(不影响整个画布)
解决这个问题的核心是手动为每个曲面生成颜色数组,而非依赖全局colormap设置。以下是具体实现步骤和代码示例:
核心思路
- 为每个曲面单独指定目标colormap
- 将曲面的数据(如Z值)归一化到0-1区间,适配colormap的输入范围
- 用colormap将归一化后的数据转换成RGBA颜色数组,直接传给
plot_surface的facecolors参数 - 可选:为每个曲面创建独立的色条(colorbar)
完整代码示例
import matplotlib.pyplot as plt import numpy as np from matplotlib.cm import get_cmap, ScalarMappable # 生成基础网格数据 x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) # 定义三个不同的曲面函数 Z1 = np.sin(np.sqrt(X**2 + Y**2)) Z2 = np.cos(np.sqrt(X**2 + Y**2)) Z3 = np.sqrt(X**2 + Y**2) * 0.1 # 创建3D坐标轴 fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(projection='3d') # -------------------------- # 第一个曲面:使用viridis配色 # -------------------------- cmap_viridis = get_cmap('viridis') # 归一化Z1的值到0-1范围 norm1 = plt.Normalize(Z1.min(), Z1.max()) # 生成颜色数组 colors_viridis = cmap_viridis(norm1(Z1)) # 绘制曲面,传入自定义颜色 surf1 = ax.plot_surface(X, Y, Z1, facecolors=colors_viridis, shade=False) # -------------------------- # 第二个曲面:使用plasma配色(Z轴偏移2避免重叠) # -------------------------- cmap_plasma = get_cmap('plasma') norm2 = plt.Normalize(Z2.min(), Z2.max()) colors_plasma = cmap_plasma(norm2(Z2)) surf2 = ax.plot_surface(X, Y, Z2 + 2, facecolors=colors_plasma, shade=False) # -------------------------- # 第三个曲面:使用inferno配色(Z轴偏移4避免重叠) # -------------------------- cmap_inferno = get_cmap('inferno') norm3 = plt.Normalize(Z3.min(), Z3.max()) colors_inferno = cmap_inferno(norm3(Z3)) surf3 = ax.plot_surface(X, Y, Z3 + 4, facecolors=colors_inferno, shade=False) # -------------------------- # 为每个曲面添加独立色条 # -------------------------- # 第一个曲面的色条 sm1 = ScalarMappable(norm=norm1, cmap=cmap_viridis) sm1.set_array([]) # 仅用于生成色条,无需绑定数据 fig.colorbar(sm1, ax=ax, shrink=0.5, pad=0.1, label='Z1 (viridis)') # 第二个曲面的色条 sm2 = ScalarMappable(norm=norm2, cmap=cmap_plasma) sm2.set_array([]) fig.colorbar(sm2, ax=ax, shrink=0.5, pad=0.1, label='Z2 (plasma)') # 第三个曲面的色条 sm3 = ScalarMappable(norm=norm3, cmap=cmap_inferno) sm3.set_array([]) fig.colorbar(sm3, ax=ax, shrink=0.5, pad=0.1, label='Z3 (inferno)') # 设置坐标轴标签 ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
关键细节说明
shade=False:必须关闭阴影效果,否则Matplotlib会自动调整曲面颜色,覆盖自定义的facecolors。Normalize:确保每个曲面的数据都被映射到colormap的完整范围(0-1),避免颜色失真。- 独立色条:通过
ScalarMappable绑定每个曲面的colormap和归一化规则,生成专属色条,不会互相干扰。
内容的提问来源于stack exchange,提问作者jzz11
相关产品推荐
相关产品推荐

