基于3D NumPy数组创建Matplotlib 3D曲面图:如何转换为所需的2D X、Y、Z数组
plot_surface Let's break down your questions and solve this step by step:
Key Background
Matplotlib's plot_surface(X, Y, Z) requires three 2D arrays of identical shape:
XandYform a grid of coordinates on a 2D plane (e.g., XY, YZ, or XZ)Zis the height value corresponding to each grid point
Your 3D array example_data has shape [4, 3, 6], which we'll define as:
- Dimension 0 (size 4): Y-axis coordinates
- Dimension 1 (size 3): X-axis coordinates
- Dimension 2 (size 6): Z-axis coordinates
example_data[y, x, z]= scalar value at position (y, x, z)
Answers to Your Questions
1. How to convert the 3D array to required 2D arrays?
You need to choose which 2D plane to plot (XY, YZ, or XZ), fix the third axis to a specific value, then extract the corresponding slice from your 3D array as the height data. Use numpy.meshgrid to generate the coordinate grid for the chosen plane.
2. Do you need arrays of shapes [4,3], [4,6], [3,6]?
No—each call to plot_surface requires three arrays of the same shape. Those different shapes correspond to different planes:
[4,3]for XY-plane plots (fixed Z value)[4,6]for YZ-plane plots (fixed X value)[3,6]for XZ-plane plots (fixed Y value)
3. Can numpy.meshgrid be used?
Absolutely! meshgrid is the standard tool to generate the 2D coordinate grids needed for plot_surface.
Practical Code Examples
Example 1: Plot an XY-plane surface (fixed Z value)
Let's plot the surface at z=2 (third slice of your 3D array):
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 ]]]) # Define coordinate points for each axis x_points = np.arange(example_data.shape[1]) # X-axis: 0,1,2 y_points = np.arange(example_data.shape[0]) # Y-axis: 0,1,2,3 z_points = np.arange(example_data.shape[2]) # Z-axis: 0-5 # Generate 2D grid for X and Y X, Y = np.meshgrid(x_points, y_points) # Extract height data for z=2 Z_surface = example_data[:, :, 2] # Plot the surface fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') surf = ax.plot_surface(X, Y, Z_surface, cmap='viridis', edgecolor='none') # Add labels and colorbar ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Scalar Value') ax.set_title(f'Surface at Z = {z_points[2]}') fig.colorbar(surf, shrink=0.5, aspect=5) plt.show()
Example 2: Plot 3 orthogonal surfaces (like your contourf example)
Replace your contourf calls with plot_surface to get 3D surfaces on each plane:
Nx, Ny, Nz = 3, 4, 6 X, Y, Z = np.meshgrid(np.arange(Nx), np.arange(Ny), -np.arange(Nz)) data = example_data kw = {'vmin': data.min(), 'vmax': data.max(), 'cmap': 'viridis', 'edgecolor': 'none'} fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='3d') # XY-plane at z=0 ax.plot_surface(X[:, :, 0], Y[:, :, 0], data[:, :, 0], offset=0, **kw) # YZ-plane at x=0 ax.plot_surface(np.full_like(Y[0, :, :], 0), Y[0, :, :], data[0, :, :], offset=0, **kw) # XZ-plane at y=Ny-1 ax.plot_surface(X[:, -1, :], np.full_like(X[:, -1, :], Ny-1), data[:, -1, :], offset=X.max(), **kw) # Set axis limits and labels ax.set_xlim(0, Nx-1) ax.set_ylim(0, Ny-1) ax.set_zlim(-(Nz-1), 0) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
Example 3: 3D Contour Plot (like the Matplotlib reference)
If you want to replicate the 3D contour plot from the Matplotlib gallery, use contour3D with a 3D coordinate grid:
# Generate 3D coordinate grid X3D, Y3D, Z3D = np.meshgrid(x_points, y_points, z_points, indexing='ij') fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') # Plot 3D contours (10 levels) ax.contour3D(X3D, Y3D, Z3D, example_data, levels=10, cmap='viridis') ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Z Axis') ax.set_title('3D Contour Plot of the Scalar Field') plt.show()
内容的提问来源于stack exchange,提问作者Polly Gill




