Figure, Axes and Artist
Every matplotlib question is really “which object owns this?”
FigureAxesArtistfig.suptitleax.spinesax.xaxisWatch it happen
Play it through, or step back and forth yourself.
figthe whole canvasaxone plotting areaax.plot(...)returns the Line2D artistax.set_title(...)text belongs to the Axesax.spines / ax.xaxisthe frame and the scales
A finished matplotlib chart. It looks like one thing and it's actually a small tree of objects — and knowing which object owns what is most of learning matplotlib.
The idea
matplotlib has a reputation for being fiddly, and most of that comes from one thing: people learn the commands before they learn the objects. Learn the objects first and the commands stop needing to be memorised.
There are three, and they nest.
Figure — the canvas
The outermost container. It has a size in inches and a resolution in dots per inch; multiply them and you have the pixel dimensions of the file you save. It draws nothing itself.
fig = plt.figure(figsize=(6, 3.5), dpi=150) # 900 x 525 pixels
fig.suptitle("A title for the whole figure")Axes — one plotting area
Inside the Figure sit one or more Axes. An Axes is a single plot: a rectangle with its own x scale, y scale, title and labels. This is where data goes, and it's the object you'll interact with most.
The name is the single worst thing about matplotlib's API. An Axes is a whole subplot. An Axis (ax.xaxis) is one of its two scales. They differ by one letter and mean completely different things.
fig, ax = plt.subplots() # one Figure, one Axes
fig, axes = plt.subplots(2, 2) # one Figure, four AxesArtist — everything drawn
Every visible thing is an Artist: the line, the markers, the bars, the text, the legend, the tick marks, the frame. ax.plot() doesn't so much draw as create an artist and hand it back:
line, = ax.plot(days, delhi) # a Line2D
line.set_color("#66aaf9") # still editable afterwards
line.set_linewidth(3)That trailing comma is worth noticing — plot returns a list, because one call can draw several lines.
Who owns what
Almost everything you'll want to change belongs to the Axes:
ax.set_title(...) ax.set_xlabel(...) ax.legend()
ax.set_xlim(...) ax.set_xticks(...) ax.grid(...)
ax.spines["top"] ax.xaxis ax.yaxisThe Figure owns only the things that are about the whole canvas — fig.suptitle(), fig.savefig(), fig.set_size_inches(), fig.tight_layout().
So when you don't know how to change something, ask which object owns it. Tick colour? The axis, via the Axes. Frame? A spine, via the Axes. Overall size? The Figure. That one question replaces a lot of searching.
Looking inside
fig.axes # every Axes in this figure
ax.get_figure() # back up to the Figure
ax.lines # the Line2D artists on this Axes
ax.get_children() # everything the Axes ownsax.get_children() is genuinely useful when you're stuck: it lists every artist on the Axes, and the thing you want to change is in there somewhere.
See it run
The lesson's code, ready to run and to fiddle with.
Putting the kettle on…
Starting up…
Worked example
not gradedAlready written and ready to go — press Run to see what it does, then change a number, a column name, anything, and run it again.
tryprinting ax.get_children() to see everything the Axes owns.
Your turn
3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.
Create a figure and axes with plt.subplots(), and return the type name of the first object — it should be Figure.
Make a figure with four Axes in a 2×2 grid, and return how many Axes the figure contains.
Plot delhi against days and return the type name of the artist that ax.plot() hands back. Remember it returns a list.
