Unit 09.03: Saving a figure that survives a slide deck
A figure that looks right on your screen often looks wrong in a slide deck.
Format, resolution and the whitespace problem
The same figure saved three ways, with the file sizes and what each suits.
The code saves each and reports.
import io
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 3.5))
ax.plot([1, 2, 3], [2, 4, 3])
ax.set_title("Weekly defect rate")
print(f"{'format':>6} {'dpi':>5} {'bytes':>9} suits")
for fmt, dpi, suits in [("png", 100, "email, quick share"),
("png", 200, "slides on a large screen"),
("svg", 0, "anything that may be resized")]:
buf = io.BytesIO()
kwargs = {"format": fmt, "bbox_inches": "tight"}
if dpi:
kwargs["dpi"] = dpi
fig.savefig(buf, **kwargs)
print(f"{fmt:>6} {dpi or '-':>5} {len(buf.getvalue()):>9,} {suits}")
plt.close(fig)
print("\n`bbox_inches='tight'` crops the whitespace that otherwise makes a")
print("figure look small and off-centre when pasted into a slide.")
bbox_inches="tight" is the setting that matters most and is left out most often. Without it, Matplotlib keeps generous default margins, and the pasted figure appears small and off-centre inside a large transparent rectangle.
SVG is worth defaulting to for anything that might be resized. It stays sharp at any size, and the text remains selectable and searchable.
The mistake this prevents
The mistake is exporting at screen resolution for a projected slide. A 100-dpi PNG that looks crisp in a browser is visibly soft on a large screen, and the axis labels are the first thing to become unreadable.
Takeaway
Save with bbox_inches="tight", use SVG where it may be resized, and raise the resolution for anything that will be projected.
