如何利用3D NumPy数组制作Matplotlib 3D曲面图?
解决3D数组转plot_surface所需2D数组的问题
核心前提
plot_surface的输入要求非常明确:
- 需要两个自变量的2D网格矩阵(
X、Y,形状必须一致) - 对应每个网格点的高度值2D矩阵(
Z,形状与X、Y完全匹配)
你的example_data是形状为(4,3,6)的三维标量场([y轴采样数, x轴采样数, z轴采样数]),要生成曲面图,必须先确定哪两个维度作为自变量网格,哪个维度(或标量值)作为高度。
具体实现方案
方案1:固定z轴,展示x-y平面上的标量值高度
选择z轴的某个固定切片(比如z=0),将该切片的标量值作为高度,x、y作为自变量网格:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D example_data = np.array([[[ 0. , -0.17641481, -0.72472288, -1.634733 , -2.88745155, -4.45446602], [-0.13739369, -0.31310624, -0.85886054, -1.76420826, -3.01012461, -4.56879708], [-0.35161935, -0.52612019, -1.06770701, -1.96573273, -3.20127564, -4.74702167]], [[-0.04258234, -0.21878815, -0.76633309, -1.67490601, -2.92547351, -4.48988789], [-0.19878962, -0.37417798, -0.91875395, -1.82200802, -3.06494007, -4.61990366], [-0.43114388, -0.60516764, -1.14515408, -2.04045165, -3.27220115, -4.81316763]], [[-0.10061408, -0.27653455, -0.82302458, -1.7296353 , -2.97729546, -4.53817427], [-0.27544339, -0.4504148 , -0.99350961, -1.89414589, -3.1333632 , -4.68370029], [-0.52562477, -0.69907413, -1.23715577, -2.12921336, -3.35644715, -4.89172916]], [[-0.17403085, -0.34958509, -0.89471911, -1.79884052, -3.04285776, -4.59927476], [-0.36725838, -0.54171551, -1.08302212, -1.9805198 , -3.21529955, -4.76010013], [-0.63493209, -0.80770802, -1.34358099, -2.23188968, -3.45389109, -4.9825877 ]]]) # 定义x、y轴的采样点 x = np.arange(3) y = np.arange(4) # 生成x-y网格,形状为(4,3),与example_data[:, :, z_idx]匹配 X, Y = np.meshgrid(x, y) # 取z=0的切片作为高度Z Z = example_data[:, :, 0] # 绘制曲面图 fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.plot_surface(X, Y, Z, edgecolor='royalblue', lw=0.5, rstride=1, cstride=1, alpha=0.7) plt.show()
方案2:固定y轴,展示x-z平面上的标量值高度
选择y轴的某个固定切片(比如y=0),将该切片的标量值作为高度,x、z作为自变量网格:
# 定义x、z轴的采样点(z轴方向与你之前的代码一致) x = np.arange(3) z = -np.arange(6) # 生成x-z网格,形状为(6,3) X, Z = np.meshgrid(x, z) # 取y=0的切片并转置,匹配网格形状(6,3) Y_surface = example_data[0, :, :].T # 绘制曲面图 fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.plot_surface(X, Y_surface, Z, edgecolor='darkred', lw=0.5, rstride=1, cstride=1, alpha=0.7) plt.show()
关于meshgrid的说明
完全可以用meshgrid生成所需的2D网格:
- 当需要x-y网格时,
np.meshgrid(x, y)生成的X、Y形状为(len(y), len(x)),正好匹配example_data[:, :, z_idx]的(4,3)形状 - 当需要x-z网格时,
np.meshgrid(x, z)生成的X、Z形状为(len(z), len(x)),此时需将example_data[y_idx, :, :]转置以匹配网格形状
额外说明:三维标量场等值面
如果你的需求是展示某个标量值对应的三维曲面(比如所有example_data[y,x,z] = -1的点组成的曲面),matplotlib本身没有直接的等值面绘制函数,可使用mayavi库的mlab.contour3d实现,或用你之前的contourf代码绘制多平面等高线进行近似。
内容的提问来源于stack exchange,提问作者Polly Gill
相关产品推荐
相关产品推荐

