Typst Report¤
The TypstReport class lets you build PDF reports from your matplotlib figures using Typst. You compose a report by adding paragraphs and figure grids, then compile everything to a PDF with a single call.
Prerequisites¤
You need the typst CLI installed to compile reports to PDF. See the Typst installation guide.
# macOS
brew install typst
# or via cargo
cargo install typst-cli
Basic usage¤
Create a report, add some content, and save it:
from bessaplots import TypstReport
report = TypstReport(
title="My Experiment Results",
author="J. Doe",
paper_size="a4",
)
report.add_paragraph("This report summarises the results of our experiment.")
report.add_figures(["figures/fig1.pdf", "figures/fig2.pdf"], columns=2)
# Writes report.typ and compiles report.pdf
report.save("report")
The date parameter defaults to today's date. You can set it explicitly or pass an empty string to omit it:
# Explicit date
report = TypstReport(title="Report", date="2026-01-15")
# No date line
report = TypstReport(title="Report", date="")
Adding figures¤
The add_figures() method places images in a grid layout. It supports several options for controlling the layout.
Columns¤
Pass an integer for equal-width columns, or a list of Typst width strings for custom widths:
# Two equal-width columns
report.add_figures(["fig1.pdf", "fig2.pdf"], columns=2)
# Custom column widths (1:2 ratio)
report.add_figures(["fig1.pdf", "fig2.pdf"], columns=["1fr", "2fr"])
Captions and subcaptions¤
Add a caption to wrap the grid in a Typst #figure block with automatic numbering. Use subcaptions for per-image labels:
# Overall caption
report.add_figures(
["fig1.pdf", "fig2.pdf"],
columns=2,
caption="Comparison of methods A and B.",
)
# Per-image subcaptions
report.add_figures(
["fig1.pdf", "fig2.pdf"],
columns=2,
caption="Comparison of methods A and B.",
subcaptions=["Method A", "Method B"],
)
Splitting across pages¤
When you have many figures, use rows_per_page to automatically insert page breaks:
# 3 columns, max 2 rows per page
report.add_figures(
[f"fig{i}.pdf" for i in range(12)],
columns=3,
rows_per_page=2,
caption="All results.",
)
The caption is placed on the last page only.
Write and compile separately¤
If you want to inspect or edit the .typ source before compiling, use write() and compile() separately:
# Step 1: generate the .typ source file
typ_path = report.write("report")
print(typ_path) # /absolute/path/to/report.typ
# Step 2: compile to PDF
pdf_path = report.compile(typ_path)
print(pdf_path) # /absolute/path/to/report.pdf
Paper sizes¤
Three paper sizes are supported:
| Value | Paper size |
|---|---|
"a4" |
A4 (default) |
"letter" |
US Letter |
"b5" |
ISO B5 |
report = TypstReport(title="US Letter Report", paper_size="letter")
Full example¤
Combining bessaplots figure creation with a Typst report:
import matplotlib.pyplot as plt
import numpy as np
from bessaplots import TypstReport, set_size
plt.style.use("bessaplots")
# Create two figures
figures = []
for _i, func in enumerate([np.sin, np.cos]):
fig, ax = plt.subplots(figsize=set_size(paper_size="a4"))
x = np.linspace(0, 2 * np.pi, 100)
ax.plot(x, func(x))
ax.set_xlabel("$x$")
ax.set_ylabel(f"${func.__name__}(x)$")
path = f"fig_{func.__name__}.pdf"
fig.savefig(path, bbox_inches="tight")
figures.append(path)
plt.close(fig)
# Build the report
report = TypstReport(
title="Trigonometric Functions",
author="J. Doe",
paper_size="a4",
)
report.add_paragraph(
"This report shows the sine and cosine functions over one full period."
)
report.add_figures(
figures,
columns=2,
caption="Sine and cosine.",
subcaptions=["Sine", "Cosine"],
)
report.save("trig_report")