The final figure of a paper is rarely one plot — it is panels (a), (b), © sized for a journal column. This lesson assembles a two-panel figure the print-ready way: explicit figure size, shared axes, labelled panels.
Step 1 — Think in inches, once
A single-column figure is ~3.4 inches wide. Fix the size up front and every font decision becomes real:
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1, ax2) = plt.subplots(
2, 1, figsize=(3.4, 4.6), sharex=True, constrained_layout=True
)
sharex=True ties the panels to one x-axis; constrained_layout keeps labels from colliding without manual nudging.
Step 2 — Panel (a): the data with error bars
With axes objects, every call names its panel explicitly:
x = np.arange(1, 9)
y = np.array([2.1, 3.9, 8.3, 15.8, 31.0, 44.2, 58.9, 71.5])
yerr = np.array([0.4, 0.5, 0.9, 1.4, 2.2, 2.7, 3.1, 3.6])
ax1.errorbar(x, y, yerr=yerr, fmt="o", markersize=4,
capsize=3, linewidth=1)
ax1.set_ylabel("Signal")
fmt="o" plots markers without a connecting line — measured points are points; only models get lines.
Step 3 — Panel (b): the residuals
The panel that convinces a referee — how far the data sit from the model:
model = 1.15 * x ** 2
ax2.axhline(0, linewidth=0.8, color="gray")
ax2.errorbar(x, y - model, yerr=yerr, fmt="o", markersize=4, capsize=3)
ax2.set_xlabel("Concentration")
ax2.set_ylabel("Residual")
Step 4 — Label the panels
The (a)/(b) letters journals expect, in axes coordinates so they survive any rescale:
for ax, label in [(ax1, "(a)"), (ax2, "(b)")]:
ax.text(0.02, 0.95, label, transform=ax.transAxes,
fontweight="bold", va="top")
Step 5 — Set the type size for print
Sizes are in points — the same points as your paper’s text. Near the document’s footnote size reads right:
plt.rcParams.update({"font.size": 9})
Put this at the top of the script (before the plotting) so every label inherits it. A Journal Style from the side panel does the same job when you’d rather match a venue’s preset.
Step 6 — Export or insert
Export / Insert — the vector PDF at this exact size drops into a single column without scaling, which is the whole point: what you designed at 3.4 inches is what prints at 3.4 inches.
Tip: If a figure looks fine in the preview but the text is huge or tiny in the compiled paper, the figure was scaled in LaTeX. Match
figsizeto the column and include it atwidth=\linewidth— design at final size, never rescale into it.
Multi-panel compositions of separate figures — a chart next to a diagram next to an image — are what Compose is for; this lesson’s subplots are for panels that share data and axes.