Grids of plots with subplots

Matplotlib · Essentials · 10 min

Small multiples, comparing panels side by side, are one of the clearest ways to show data, and they all start here.

plt.subplots(nrows, ncols) creates a Figure with a grid of Axes. What it returns depends on the shape:

  • 1, 1 (the default): a single Axes object.
  • one row or one column: a 1D NumPy array of Axes, which you can unpack: fig, (ax1, ax2) = plt.subplots(1, 2).
  • a real grid: a 2D array indexed as axs[row, col].

Passing squeeze=False always returns a 2D array, which is handy in code that builds grids of variable size. To loop over every Axes regardless of shape, use axs.flat.

sharex=True or sharey=True links the limits of the panels, so zooming or setting a limit on one applies to all, and inner tick labels are hidden to save space. Use "row" or "col" to share only along rows or columns. Shared axes are what make panels honestly comparable.

figsize is the size of the whole figure, so make it larger as you add panels. Combine with layout="constrained" so titles and tick labels of neighboring panels do not collide.

Empty cells, for instance seven plots in a 2x4 grid, can be hidden with axs[1, 3].set_axis_off() or removed with fig.delaxes. For unequal sizes, such as one wide plot above two small ones, move on to subplot_mosaic or GridSpec.

Example

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1, 50)
fig, axs = plt.subplots(2, 3, figsize=(9, 5), sharex=True, sharey=True,
                        layout="constrained")
print(axs.shape)                       # (2, 3)

for k, ax in enumerate(axs.flat[:5]):
    ax.plot(x, x ** (k + 1))
    ax.set_title(f"x^{k + 1}")
axs[1, 2].set_axis_off()               # hide the unused sixth panel

axs[0, 0].set_ylim(0, 2)               # shared: applies to every panel
print([float(v) for v in axs[1, 1].get_ylim()])  # [0.0, 2.0]
fig.savefig("grid.png")

Remember

  • plt.subplots(r, c) returns a scalar, 1D or 2D array of Axes depending on shape
  • Iterate with axs.flat; index grids as axs[row, col]
  • sharex/sharey make panels directly comparable

Watch out for

  • Indexing axs[0] on a 2D grid and getting a whole row instead of one Axes.

Check yourself

  1. `fig, axs = plt.subplots(1, 3)`. What is `axs`?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplots.html