Basic Plots
18 min
Matplotlib's core mental model: plt.subplots() returns a Figure and
an Axes object, and everything else — ax.plot(), ax.set_xlabel(),
ax.bar() — mutates that same Axes in place. Because the Axes is a
real Python object, you can inspect it programmatically: how many lines
did I actually add? What's the axis label set to? This is exactly how
real matplotlib test suites verify plotting code, without ever
comparing rendered pixels.
import matplotlib
matplotlib.use("AGG")
import matplotlib.pyplot as plt
def count_lines_and_label(x, y_series_list, xlabel):
fig, ax = plt.subplots()
for y in y_series_list:
ax.plot(x, y)
ax.set_xlabel(xlabel)
return (len(ax.get_lines()), ax.get_xlabel())
matplotlib.use with the AGG backend selects a non-interactive renderer that draws to an in-memory buffer instead of trying to open a display window -- essential in any headless environment (a server, a test runner, or this sandbox) where there's no screen to show a plot on.
Write `count_lines_and_label(x, y_series_list, xlabel)`: create a figure and axes with `plt.subplots()`, call `ax.plot(x, y)` once for each series in `y_series_list`, set the x-axis label to `xlabel`, and return `(len(ax.get_lines()), ax.get_xlabel())`.
Why does this exercise grade a plot by inspecting `ax.get_lines()` and `ax.get_xlabel()` instead of comparing the rendered image?
You can build a plot with matplotlib's Figure/Axes API and verify its structure by inspecting the resulting objects directly, the same technique real plotting-code test suites use.