Library Overview02/06
Starting sandbox…
Beginner

Matplotlib

Matplotlib

Core Principle: Matplotlib is a hierarchical graphics rendering library in which every visual element is represented as an explicit Artist object within a Figure and Axes hierarchy.

Version at time of writing: 3.11.x · import matplotlib.pyplot as plt

Architectural Hierarchy

Three nested containers, and one rule.

graph TD A["Figure (Canvas, DPI, Serialization)"] --> B["Axes (Data Area, Ticks, Labels)"] B --> C["Artist (Line2D, Text, Patch, Collection)"]

The rule: everything you see is an Artist attached to an Axes, and every Artist has getters and setters. If you can see it, you can change it. That is why matplotlib is verbose and why it provides complete graphical control: every component can be programmatically adjusted to meet publication standards.

"Axes" means a panel, not an axis. A 2×2 grid has four Axes. The x-axis of one panel is ax.xaxis. This naming causes real confusion; see Figure and Axes.

Explicit Object-Oriented Interface

Use the object-oriented API, not the implicit plt. state machine:

fig, ax = plt.subplots(figsize=(6, 4))
ax.scatter(x, y)
ax.set_xlabel("log2 fold change")
fig.savefig("plot.pdf", bbox_inches="tight")

not

plt.scatter(x, y)
plt.xlabel("log2 fold change")   # ← which Axes did this hit?
plt.savefig("plot.pdf")

The plt. form writes to whatever the "current" Axes happens to be, which breaks the moment you have subplots, a loop, or a seaborn call in between. See pyplot vs Object-Oriented API.

Computational Relevance in Biology

Journals want vector figures at specific column widths with editable text. Only matplotlib gives you that control: exact figure sizes in inches, fonts embedded as text rather than paths, colourblind-safe palettes, and per-Artist tweaking for the one gene label that overlaps another. Seaborn gets you 90% of the way in one line, and then you reach through to matplotlib for the last 10%.

Core Reference Modules

Structure Figure and Axes · pyplot vs Object-Oriented API · Matplotlib Artists · Subplots and Layout

Content Common Plot Types · Axes Styling and Annotation · Colormaps and Color

Output Saving Figures · rcParams and Style Sheets

Applied Workflows

Applied - Differential Expression Volcano Plot · Applied - Heatmaps and Clustermaps · Applied - Quality Control Plots

Installation and Verification

pip install "matplotlib>=3.10,<4"
python -c "import matplotlib; print(matplotlib.__version__, matplotlib.get_backend())"

If figures do not appear, the backend is usually the culprit. In a headless script or container use matplotlib.use("Agg") before importing pyplot and save to file rather than showing.

Essential API Patterns

fig, axes = plt.subplots(1, 2, figsize=(10, 4), sharey=True, layout="constrained")

axes[0].scatter(x, y, s=8, alpha=0.5, c=colours)
axes[0].axhline(0, ls="--", lw=1, color="grey")
axes[0].set(xlabel="log2FC", ylabel="-log10 p", title="Volcano")

axes[1].hist(y, bins=50)
axes[1].set_xlabel("-log10 p")

fig.savefig("figure.pdf", bbox_inches="tight")
plt.close(fig)

layout="constrained" (the modern replacement for tight_layout()) fixes overlapping labels automatically. plt.close(fig) in loops prevents the memory leak that produces the "More than 20 figures have been opened" warning.

Common Pitfalls & Behavioral Edge Cases

  • Figures never close in a loop → memory grows until the process dies. Always plt.close(fig).
  • Text saved as paths instead of glyphs, so editors cannot change it. Set rcParams["pdf.fonttype"] = 42. See Saving Figures.
  • Jet / rainbow colormaps. They are perceptually non-uniform and invent structure that is not there. Use viridis. See Colormaps and Color.
  • plt.show() inside a script blocks; inside a notebook it is usually redundant.
  • Resizing after saving has no effect because figure serialization records the state at invocation time.

Related References

Seaborn · Ecosystem Map · Pandas