Matplotlib 3D
Quick 3D Plots with Matplotlib
Matplotlib's mpl_toolkits.mplot3d module provides basic 3D
plotting: surfaces, wireframes, scatter, and contour plots.
It is not a true 3D renderer β it projects 3D objects onto 2D
using painter's algorithm β but for quick exploratory visualization
and journal figures, it is often sufficient.
Definition: Creating 3D Axes
Creating 3D Axes
Add projection='3d' to create a 3D Axes:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# or
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
Key methods: ax.plot_surface(), ax.plot_wireframe(),
ax.scatter3D(), ax.plot3D(), ax.contour3D().
The 3D axes support ax.view_init(elev, azim) to set the
camera angle.
Definition: Surface Plots
Surface Plots
ax.plot_surface(X, Y, Z, cmap, **kwargs) renders a 3D surface
from meshgrid arrays:
x = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, x)
Z = np.sinc(np.sqrt(X**2 + Y**2))
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
surf = ax.plot_surface(X, Y, Z, cmap='viridis',
alpha=0.8, edgecolor='none')
fig.colorbar(surf, shrink=0.6)
Definition: Wireframe and 3D Scatter
Wireframe and 3D Scatter
Wireframe shows the mesh structure without filling:
ax.plot_wireframe(X, Y, Z, color='blue', linewidth=0.5,
rstride=5, cstride=5)
3D Scatter places points in 3D space:
ax.scatter3D(xs, ys, zs, c=colors, s=sizes, cmap='viridis')
Theorem: Matplotlib 3D Limitations
Matplotlib's 3D rendering uses a 2D projection with painter's algorithm (back-to-front sorting). This means:
- No true depth testing β intersecting surfaces render incorrectly.
- No lighting β surfaces are flat-shaded by colormap only.
- Performance β degrades rapidly beyond ~ polygons.
For interactive 3D, volume rendering, or complex scenes, use PyVista (Section 17.2) or Plotly 3D.
Think of Matplotlib 3D as "2.5D" β it is a convenient approximation for simple surfaces and scatter plots, not a full 3D engine.
Example: Visualizing a Cost Function Surface
Plot the Rosenbrock function as a 3D surface with the minimum marked.
Implementation
x = np.linspace(-2, 2, 200)
X, Y = np.meshgrid(x, x)
Z = (1 - X)**2 + 100 * (Y - X**2)**2
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}, figsize=(8, 6))
surf = ax.plot_surface(X, Y, np.log10(Z + 1),
cmap='viridis', alpha=0.8, edgecolor='none')
ax.scatter([1], [1], [0], color='red', s=100, zorder=5)
ax.set(xlabel='x', ylabel='y', zlabel='log10(f+1)')
ax.set_title('Rosenbrock Function')
ax.view_init(elev=30, azim=-60)
fig.colorbar(surf, shrink=0.5)
Example: 3D Scatter: MIMO Capacity vs Parameters
Plot MIMO capacity as a function of SNR and number of antennas as a 3D scatter plot with color encoding.
Implementation
snr_db = np.repeat(np.arange(0, 31, 2), 8)
n_ant = np.tile(np.arange(1, 9), 16)
snr_lin = 10**(snr_db / 10)
capacity = n_ant * np.log2(1 + snr_lin / n_ant)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}, figsize=(8, 6))
sc = ax.scatter3D(snr_db, n_ant, capacity, c=capacity,
cmap='viridis', s=30)
ax.set(xlabel='SNR (dB)', ylabel='Antennas',
zlabel='Capacity (bits/s/Hz)')
fig.colorbar(sc, shrink=0.5, label='Capacity')
Example: Surface with Projected Contours
Show a 3D surface with contour lines projected onto the floor.
Implementation
x = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, x)
Z = np.sinc(np.sqrt(X**2 + Y**2))
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}, figsize=(8, 6))
ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.7, edgecolor='none')
ax.contour(X, Y, Z, zdir='z', offset=-0.5, cmap='viridis', levels=15)
ax.set_zlim(-0.5, 1.0)
ax.set_title('Surface with Floor Contours')
3D Surface Explorer
Explore different mathematical surfaces in 3D with adjustable viewing angles and colormaps.
Parameters
Common Mistake: Matplotlib 3D Depth Sorting Artifacts
Mistake:
Plotting two intersecting surfaces in Matplotlib 3D produces visual artifacts where one surface incorrectly occludes the other.
Correction:
For intersecting geometry, switch to PyVista or Plotly 3D which
have proper depth testing. Alternatively, increase alpha
transparency on both surfaces.
Key Takeaway
Use Matplotlib 3D for simple surfaces and journal figures. It produces publication-quality vector output and integrates with your existing Matplotlib workflow. For interactive exploration or complex 3D scenes, switch to PyVista or Plotly.
Quick Check
What does ax.view_init(elev=45, azim=-60) do?
Sets the figure size
Sets the 3D camera elevation and azimuth angles
Initializes the animation
Sets the axis limits
elev is the vertical angle (degrees above the xy-plane), azim is the horizontal rotation.
Surface Plot
A 3D visualization that renders a function z=f(x,y) as a colored mesh of quadrilaterals.
Wireframe Plot
A 3D visualization showing only the mesh edges without filled surfaces, useful for seeing through the geometry.
Historical Note: Matplotlib 3D History
2007The mplot3d toolkit was contributed by John Porter in 2007 as an
add-on to Matplotlib. Despite its limitations (no true depth buffer),
it remained the default Python 3D plotting tool for over a decade
because of its tight integration with Matplotlib's ecosystem. In the
2020s, PyVista and Plotly have emerged as superior alternatives for
interactive 3D work.