Matplotlib Subplots Function
plt.subplots() creates a figure and a grid of Axes objects together in one call, giving you individual variables to control each plot instead of repeated subplot() calls.
A Cleaner Way to Build Grids
The older plt.subplot() function works fine for a couple of plots, but repeating it for every cell in a larger grid gets verbose, and it does not give you a direct handle to each plot's axes. plt.subplots() (note the 's' — it is a different function) solves this by creating the whole figure and grid of Axes objects in one call and handing them back to you as objects you can act on directly.
Basic Usage
fig, ax = plt.subplots() creates a figure with a single plot area, returning the Figure object and one Axes object. When you ask for a grid, ax becomes a NumPy array of Axes objects instead of a single one.
Example
import matplotlib.pyplot as plt
import numpy as np
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([0, 1, 4, 9, 16, 25])
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title("A single Axes object")
plt.show()Creating a Grid of Plots
Pass the number of rows and columns to plt.subplots(nrows, ncols) to build a grid. The returned ax is a 2D NumPy array shaped (nrows, ncols), so you index it like ax[0, 0] for the top-left plot and ax[1, 1] for the plot in the second row, second column.
Example
import matplotlib.pyplot as plt
import numpy as np
months = np.array(["Jan", "Feb", "Mar", "Apr"])
product_a = np.array([120, 135, 150, 170])
product_b = np.array([80, 95, 88, 102])
fig, ax = plt.subplots(2, 2, figsize=(8, 6))
ax[0, 0].plot(months, product_a)
ax[0, 0].set_title("Product A - Line")
ax[0, 1].bar(months, product_a)
ax[0, 1].set_title("Product A - Bar")
ax[1, 0].plot(months, product_b)
ax[1, 0].set_title("Product B - Line")
ax[1, 1].bar(months, product_b)
ax[1, 1].set_title("Product B - Bar")
fig.suptitle("Quarterly comparison")
fig.tight_layout()
plt.show()- One function call builds the entire figure and grid, rather than one call per plot.
- Each Axes object is a named variable you can pass around, store in a list, or loop over.
- The figsize argument sizes the whole figure once, instead of being set separately for each plot.
- sharex=True and sharey=True let every plot in the grid share the same axis scale, which keeps comparisons fair.
Example
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(1, 2, sharey=True, figsize=(8, 4))
ax[0].plot(x, np.sin(x))
ax[0].set_title("Sine wave")
ax[1].plot(x, np.cos(x))
ax[1].set_title("Cosine wave")
plt.show()Exercise: Matplotlib Subplots
In plt.subplot(2, 3, index), what do the first two arguments represent?