You can't draw straight onto a blank Figure — McKinney is explicit about this: "You
can't make a plot with a blank figure. You have to create one or more subplots." The
convenient shortcut plt.subplots(nrows, ncols) creates the figure and a NumPy array
of Axes in one call, so you can index into it like axes[0, 1] for "row 0, column 1."
flowchart TD A["plt.subplots(2, 2)"] --> B["fig"] A --> C["axes - a 2x2 array of Axes"] C --> D["axes[0, 0]"] C --> E["axes[0, 1]"] C --> F["axes[1, 0]"] C --> G["axes[1, 1]"] D --> H["Each axes plots independently"]
Subplots
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, figsize=(10, 6))
axes[0, 0].plot([1, 2, 3], [1, 4, 9])
axes[0, 0].set_title("Line")
axes[0, 1].bar(["A", "B", "C"], [5, 2, 7])
axes[0, 1].set_title("Bar")
axes[1, 0].hist([1, 1, 2, 2, 2, 3, 4], bins=4, edgecolor="black")
axes[1, 0].set_title("Histogram")
axes[1, 1].scatter([1, 2, 3, 4], [10, 11, 9, 12])
axes[1, 1].set_title("Scatter")
fig.suptitle("Mini dashboard")
plt.tight_layout()
plt.show()Figure size rules
- Use larger figures for long labels and multiple subplots.
- Smaller is fine for single simple plots.
Visualize it
A Figure is just the outer frame — each mini panel inside is its own independent
Axes with its own data, ticks, and title:
Tip
plt.tight_layout() prevents label overlaps in most cases.
Check your understanding
What does plt.subplots(2, 2) return?
You index the array, for example axes[0, 1] for row 0 and column 1.
Show answer
A — A Figure and a 2 by 2 NumPy array of Axes — You index the array, for example axes[0, 1] for row 0 and column 1.
Which Axes holds the bar chart in the 2x2 example?
The line chart is at axes[0, 0], the bar at axes[0, 1], the histogram at axes[1, 0] and the scatter at axes[1, 1].
Show answer
A — axes[0, 1] — The line chart is at axes[0, 0], the bar at axes[0, 1], the histogram at axes[1, 0] and the scatter at axes[1, 1].
What does fig.suptitle("Mini dashboard") set?
Each Axes keeps its own set_title, while suptitle names the entire figure.
Show answer
A — A title for the whole Figure above all subplots — Each Axes keeps its own set_title, while suptitle names the entire figure.
What does plt.tight_layout() do?
It adjusts spacing between subplots so titles and labels do not collide.
Show answer
A — Prevents label overlaps in most cases — It adjusts spacing between subplots so titles and labels do not collide.
Next
Continue to Axis Labels and Titles to make every one of those panels self-explanatory.
🧪 Try It Yourself
Exercise 1 – Create a grid of axes
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – Index into the grid
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – Share an axis across subplots
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.