0 · Introduction & Scope

Matplotlib is Python’s de‑facto 2D/3D plotting library. This guide covers everything from quick pyplot sketches to the full object‑oriented (OO) API, including new features up to v3.10.1 (released 27 Feb 2025) .

Note: Every snippet runs on Python 3.9+ and Matplotlib ≥3.3; optional features need ≥3.7.

1 · Installation & Environment

1.1 · Basic Install


# stable release (pip)
python -m pip install matplotlib
# or from conda‑forge
conda install -c conda-forge matplotlib
      

1.2 · Optional Extras

1.3 · Import Conventions


import matplotlib.pyplot as plt        # pyplot helper state‑machine
from matplotlib import cm              # colour‑maps
import numpy as np
      

2 · Figure & Axes Anatomy

The OO approach is explicit: you create a Figure then add one or more Axes (the real plot containers).


fig = plt.figure(figsize=(6,4), dpi=100)
ax  = fig.add_subplot(1, 1, 1)         # rows, cols, index
ax.plot([0, 1], [0, 1], label="linear")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("Basic OO plot")
fig.tight_layout()
plt.show()
      

Key methods

3 · Pyplot State‑Machine API

3.1 · Hello World


plt.figure()
plt.plot([0, 1, 2], [0, 1, 0], marker="o")
plt.title("Pyplot quick‑start")
plt.xlabel("x‑axis")
plt.ylabel("y‑axis")
plt.show()
      

3.2 · Multiple Figures & Axes


fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8,3), sharey=True)
ax1.plot(np.sin(np.linspace(0, 2*np.pi, 100)))
ax1.set_title("sin")
ax2.plot(np.cos(np.linspace(0, 2*np.pi, 100)), color="orange")
ax2.set_title("cos")
      

Tip: plt.subplots() returns both figure and axes – a convenient bridge between state‑machine and OO style.

4 · Common Plot Types

4.1 · Lines & Markers


ax.plot(x, y,
        linestyle="--", linewidth=2,
        marker="s", markersize=6, markerfacecolor="white")
      

4.2 · Scatter & Bubble


scatter = ax.scatter(x, y, c=y, s=(y*20)**2, cmap="viridis", alpha=.8)
fig.colorbar(scatter, ax=ax, label="value")
      

4.3 · Histograms & KDE


ax.hist(data, bins=30, density=True, histtype="stepfilled", alpha=.6)
      

4.4 · Bar & Errorbar


ax.bar(categories, counts, yerr=errors, capsize=4)
      

4.5 · Images & Heatmaps


im = ax.imshow(matrix, cmap="plasma", origin="lower")
fig.colorbar(im, ax=ax)
      

5 · Styling, Themes & Fonts

5.1 · Global rcParams


import matplotlib as mpl
mpl.rcParams["font.family"] = "DejaVu Sans"
mpl.rcParams.update({"figure.facecolor": "#f9f9f9"})
      

5.2 · Built‑in Style‑Sheets


plt.style.use("seaborn-v0_8")      # improved seaborn‑compat style
# available styles: plt.style.available
      

5.3 · Your Own Style‑Sheet


with plt.rc_context({"axes.prop_cycle": cycler(color=["#ff6f69", "#96ceb4"])}):
    ax.plot(...)
      

Store custom styles as ~/.config/matplotlib/stylelib/your_style.mplstyle and load them with plt.style.use("your_style").

6 · Axes, Ticks & Annotations

6.1 · Ticks & Grids


ax.set_xlim(0, 10);    ax.set_ylim(-1, 1)
ax.set_xticks(range(0, 11, 2))
ax.grid(True, which="both", linestyle=":")
      

6.2 · Legend & Labels


ax.legend(title="Signal", loc="upper right", frameon=False)
      

6.3 · Annotations & Arrows


ax.annotate("peak", xy=(np.pi/2, 1), xytext=(2, .6),
            arrowprops={"arrowstyle":"->"})
      

7 · Subplots & GridSpec

7.1 · Basic Grid


fig, axes = plt.subplots(2, 3, figsize=(8,4), sharex="col", sharey="row")
for i, ax in enumerate(axes.flat):
    ax.text(.5, .5, f"ax {i}", ha="center", va="center")
fig.tight_layout()
      

7.2 · Complex Layout with GridSpec


import matplotlib.gridspec as gs
fig  = plt.figure(figsize=(6,6))
spec = gs.GridSpec(3, 3, figure=fig)
ax0  = fig.add_subplot(spec[0, :])
ax1  = fig.add_subplot(spec[1:, :2])
ax2  = fig.add_subplot(spec[1:, 2])
      

7.3 · Twin Axes


ax2 = ax.twinx()
ax2.plot(x, z, color="green", label="second y")
      

8 · Colormaps & Normalization

Matplotlib ships perceptually uniform maps like viridis, plasma and cividis.


norm = plt.Normalize(vmin=data.min(), vmax=data.max())
im   = ax.imshow(data, cmap="magma", norm=norm)
fig.colorbar(im, ax=ax, orientation="horizontal")
      

8.1 · Custom Colormap


from matplotlib.colors import ListedColormap
cmap = ListedColormap(["#00274d", "#0057b8", "#ffd200"])
plt.register_cmap("brand", cmap)
      

9 · 3‑D Plots & Animation

9.1 · 3‑D Surface


from mpl_toolkits.mplot3d import Axes3D      # implicit import
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(X, Y, Z, cmap="viridis", edgecolor="none")
      

9.2 · Animating with FuncAnimation


from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)

def init():
    ax.set_xlim(0, 2*np.pi);  ax.set_ylim(-1, 1)
    return line,

def update(frame):
    x = np.linspace(0, frame, 100)
    line.set_data(x, np.sin(x))
    return line,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 120),
                    init_func=init, blit=True, interval=30)
ani.save("sine.gif", writer="pillow")
      

10 · Interactive Widgets & Back‑Ends

10.1 · Choosing a Back‑End


mpl.use("QtAgg")          # high‑performance native
mpl.use("module://ipympl")# Jupyter ipywidgets
      

10.2 · Simple Slider Widget


from matplotlib.widgets import Slider
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=.25)
t   = np.linspace(0, 2*np.pi, 1000)
line, = ax.plot(t, np.sin(t))

axamp = plt.axes([0.25, 0.1, 0.65, 0.03])
slider = Slider(axamp, "Freq", 0.1, 10.0, valinit=1)

def on_change(val):
    line.set_ydata(np.sin(val*t))
    fig.canvas.draw_idle()
slider.on_changed(on_change)
      

11 · Saving Figures


fig.savefig("plot.png", dpi=300, bbox_inches="tight")
fig.savefig("plot.svg")        # vector
fig.savefig("plot.pdf")        # print‑quality
      

Use bbox_inches="tight" and pad_inches to trim whitespace. PNGs above 300 dpi suit publication; SVG/PDF best for print/vector.

12 · Performance & Best‑Practices

13 · What’s New in Matplotlib 3.10.x

Full release‑notes: Matplotlib 3.10.1 docs .

14 · Cheat‑Sheet Quick Reference

15 · Figure Container Template

Add images to the grid below (horizontal scroll enabled):