Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

3D Plot in Python: Matplotlib Surface, Scatter and Wireframe

Make a 3D plot in Python with Matplotlib: official surface example, scatter and wireframe, view_init angles, export, and alternatives.

Written and maintained by CASRAI Editorial Board

Last updated

Short answer. To make a 3D plot in Python, install Matplotlib, create axes with projection="3d", and call a 3D method such as scatter, plot_surface or plot_wireframe. Then fix the viewpoint with view_init and save the figure. The examples below follow Matplotlib’s official gallery (documentation version 3.11.2, read 2026-11-08).

What it is used for in research

A 3D plot shows a response over two inputs (a surface z = f(x, y)), three measured variables for each observation (a 3D scatter), or a gridded field such as a potential-energy or error surface. Researchers and graduate students most often need one in a paper figure, so this guide stresses reproducible, fixed viewpoints and file export. If the same figure is being made in another environment, see 3D plots in MATLAB and 3D plots in R.

3D plot Python: what to import

Matplotlib’s 3D support lives in the mpl_toolkits.mplot3d toolkit. Its 3D axes provide, among others, plot, scatter, bar, bar3d, plot_surface, plot_wireframe, plot_trisurf, contour, contourf, quiver and voxels. The official gallery example enables 3D axes with subplot_kw={"projection": "3d"} and does not import Axes3D, so older fig.gca(projection='3d') snippets are not needed.

Install or access (official source only)

From the Matplotlib installation page:

python -m pip install -U matplotlib
conda install -c conda-forge matplotlib

Check the install with python -c "import matplotlib; print(matplotlib.__version__, matplotlib.__file__)". The surface example also uses NumPy.

Step-by-step: a 3D plot with Matplotlib

3D plot Matplotlib, step 1: create 3D axes

  1. Import the libraries: import matplotlib.pyplot as plt and import numpy as np.
  2. Create the figure and 3D axes: fig, ax = plt.subplots(subplot_kw={"projection": "3d"}).

Step 2: a surface plot (official gallery example)

A surface needs 2D arrays of x, y and z values. np.meshgrid turns two 1D coordinate vectors into those grids (see NumPy meshgrid).

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import LinearLocator

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})

X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

surf = ax.plot_surface(X, Y, Z, cmap="coolwarm", linewidth=0, antialiased=False)

ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter('{x:.02f}')

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

In the official example, antialiased=False makes the surface opaque, and the LinearLocator and formatter lines set ten z ticks printed to two decimals.

Step 3: scatter and wireframe

For three measured variables per observation, pass three equal-length arrays: ax.scatter(x, y, z). For a lighter grid view of the same surface data, replace the surface call with ax.plot_wireframe(X, Y, Z). For scattered (non-gridded) points that you want as a surface, plot_trisurf is the matching method in the toolkit’s method list.

Step 4: fix the viewing angle

Call ax.view_init(elev=..., azim=..., roll=...). The documented signature is Axes3D.view_init(elev=None, azim=None, roll=None, vertical_axis='z', share=False), with angles in degrees, not radians.

Parameter Meaning (Matplotlib docs)
elev Angle above the x-y plane when vertical_axis is 'z'
azim Rotation around the vertical axis
roll Rotation around the viewing axis
vertical_axis Which axis points up: 'z' (default), 'x' or 'y'

Recording the three angles in your analysis script makes the figure reproducible for a manuscript revision.

Step 5: save for a paper

Use fig.savefig("figure.png", dpi=300) (or a .pdf or .svg file name) instead of relying on plt.show(). Check the target journal’s figure requirements for format and resolution.

Output and how to read it

Method Use it when
scatter Each observation has three measured values
plot_surface Values lie on a regular x-y grid (from meshgrid)
plot_wireframe You want the surface shape without filled faces
plot_trisurf Points are scattered, not gridded
contour / contourf You want level curves drawn on the 3D axes
bar3d Bars over a two-way categorical or gridded layout

All six methods appear in the mplot3d toolkit reference; the pairing with data shape is the usual meaning of each method. A colorbar, as in the example, carries the z value into a printed figure, since a single rotated view hides part of a surface. Because a 3D view projects three dimensions onto a flat page, consider whether a 2D heatmap or contour plot reads more accurately for your data; for 2D charts see bar plots in Matplotlib.

Troubleshooting

  • Objects appear in front of others from some angles. Matplotlib’s mplot3d FAQ calls this the most commonly reported issue: 3D data is reduced to 2D plus a z-order value, so intersecting objects cannot always be drawn correctly. It says complex 3D scenes are better served by Mayavi. Change the viewing angle with view_init or use a different library (below).
  • No window or no rotation. The non-interactive backends (Agg, ps, pdf, svg) work out of the box; TkAgg, an interactive default, needs tkinter, and on Linux the install page notes you may need the python3-tk package. A non-interactive backend can still save files with savefig.
  • Angles look wrong. view_init takes degrees, not radians.
  • Axis layout. The FAQ notes that label spacing, tick length and grid line width were historically hard-coded in mplot3d.

Free alternatives

Library What its documentation says Install (official docs)
Plotly Lists 3D scatter, surface, line, trisurf, mesh, isosurface, volume, cone and streamtube chart types, plus 3D camera controls pip install plotly
PyVista Installable from PyPI or conda-forge; extends to mesh formats and Jupyter rendering via optional packages pip install pyvista
Mayavi Recommended by the Matplotlib FAQ for advanced 3D scenes See the Mayavi documentation

For a Matplotlib-versus-Plotly decision on general charting, see Plotly vs Matplotlib.

FAQ

How do I make a 3D plot in Python?

Install Matplotlib, create axes with plt.subplots(subplot_kw={"projection": "3d"}), and call scatter, plot_surface or plot_wireframe on them.

How do I make a 3D plot in Matplotlib with a fixed viewpoint?

Call ax.view_init(elev, azim, roll) with angles in degrees before saving.

Do I need to import Axes3D?

The official gallery example enables 3D axes with subplot_kw={"projection": "3d"} and imports only pyplot, NumPy and a ticker class.

Which library suits complex 3D scenes?

The Matplotlib FAQ recommends Mayavi for complex 3D scenes; Plotly and PyVista are other free options with their own 3D documentation.

Sources (official docs, read 2026-11-08)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about 3D Plot in Python: Matplotlib Surface, Scatter and Wireframe

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →