Skip to course content
Free data visualization course

Data Visualization and Dashboard Storytelling

Unit 09.00: Figure and axes, and why the distinction matters

Almost every confusing Matplotlib error comes from confusing the figure with the axes.

One figure, many axes

A figure is the canvas; an axes is a single plotting panel on it. Titles, labels and limits belong to an axes; size, saving and the overall title belong to the figure.

The code creates one figure with two axes and shows which is which.

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

fig, axes = plt.subplots(1, 2, figsize=(8, 3))
print(f"figure type : {type(fig).__name__}")
print(f"axes returned: {type(axes).__name__}, {len(axes)} of them")
print(f"each one    : {type(axes[0]).__name__}")

fig.suptitle("belongs to the FIGURE -- one per figure")
axes[0].set_title("belongs to an AXES -- one per panel")
axes[0].set_xlabel("x label is per-axes too")

print("\nfigure-level things: overall title, size, saving, layout")
print("axes-level things  : the plot, its title, its labels, its limits")
plt.close(fig)

# Almost every confusing Matplotlib error comes from calling a figure method on
# an axes or the reverse. `fig, ax = plt.subplots()` and then working through
# `ax` avoids nearly all of it.

plt.subplots() returns both, and working through the returned ax rather than through the plt module avoids nearly all the confusion - plt acts on whichever axes happens to be current, which is fine for one chart and a source of silent errors for several.

The distinction also explains the naming: suptitle is the figure's title, set_title is an axes' title.

The mistake this prevents

The mistake is mixing plt. calls with ax. calls in the same function. It works until you add a second panel, at which point some of your styling lands on the wrong one - and the error is silent.

Takeaway

Use fig, ax = plt.subplots() and work through ax. Figure-level operations are size, saving and the overall title; everything else is per-axes.