plot
Compose a layered plot from data, aesthetics, and geom layers.
plot is the entry point of the grammar: it resolves the dataset, wires up the aesthetic mapping, trains scales against the data, applies coordinate, facet, theme, and label choices, and dispatches to the internal renderer. Call it once per figure, passing the layers you want to stack.
Usage
plot(
data: none,
mapping: none,
layers: (),
scales: (),
coord: none,
facet: none,
theme: none,
labels: none,
guides: (:),
width: 10cm,
height: 7cm,
alt: none,
strict: false,
as-spec: false,
)Parameters
| Parameter | Default | Description |
|---|---|---|
data |
none |
Either an array of row dictionaries (one row per observation, e.g., ((x: 1, y: 2), (x: 3, y: 4))) or a dictionary of equal-length column arrays (e.g., (x: (1, 3), y: (2, 4))). Column-store input is normalised to row-store internally. |
mapping |
none |
Aesthetic mapping built withaes. Maps column names to visual channels. |
layers |
() |
Array of geom layers (e.g., geom-point,@geom-lineGitHub). Drawn in order. |
scales |
() |
Array of scale objects overriding defaults scale-x-continuous,scale-colour-viridis-d, etc.). |
coord |
none |
Coordinate system. Defaults tocoord-cartesian when none. |
facet |
none |
Faceting specification built withfacet-wrap orfacet-grid. |
theme |
none |
Theme object (e.g., theme-grey,theme-minimal,@theme-classicGitHub). Controls non-data ink. |
labels |
none |
Labels dictionary built withlabels (title, subtitle, caption, axis titles). |
guides |
(:) |
Per-aesthetic guide overrides built withguides (e.g., guides(colour: guide-legend(reverse: true))). |
width |
10cm |
Total image width, including axes, legends, title, subtitle, caption, and plot-background padding. The data panel shrinks to leave room for chrome; long titles wrap to fit. Chrome larger than width raises an error. Pass auto to fill the available width of the container the plot sits in (resolved through Typst layout); when that container is unbounded (e.g., an auto-width page) it falls back to 10cm. Insidecompose the panel’s own width is discarded; the composition sizes each cell. |
height |
7cm |
Total image height, including axes, legends, title, subtitle, caption, and plot-background padding. The data panel shrinks to leave room for chrome. Chrome larger than height raises an error. Pass auto to fill the available height of the container (resolved through Typst layout); most predictable inside a fixed-height container such as a box or block with a set height, and falls back to 7cm when the container is unbounded. Insidecompose the panel’s own height is discarded; the composition sizes each cell. |
alt |
none |
Alt text describing the figure. When set, the rendered plot is wrapped in a figure (kind "gribouille-plot", no number, no caption) carrying this string as its PDF alternative text, so a screen reader on a tagged PDF announces the description instead of the raw axis and legend labels. When none, the plot renders without the figure wrapper. Quarto authors embedding plots through typst-render should set the block-level alt cell option for HTML output; this parameter only affects direct Typst compilation. |
strict |
false |
When true, panic on the first row whose value falls outside any user-supplied scale limits. Default false drops such rows silently. Use in docs and CI to surface mismatched limits rather than producing thinned-out plots. |
as-spec |
false |
Internal switch driven bydefer: when true, return the spec dict instead of rendering, socompose can probe guides and re-render with hoisted aesthetics suppressed. Usedefer rather than setting this directly; the dict carries the same keys the renderer would consume and must not be fed to anything other thancompose. |
Returns
Typst content block containing the rendered figure, or the spec dict when as-spec: true.
Examples
Single-layer scatter coloured by category, with a title.
#let mtcars = (
(mpg: 21.0, wt: 2.620, cyl: "6"),
(mpg: 22.8, wt: 2.320, cyl: "4"),
(mpg: 18.7, wt: 3.440, cyl: "8"),
(mpg: 16.4, wt: 4.070, cyl: "8"),
(mpg: 33.9, wt: 1.835, cyl: "4"),
)
#plot(
data: mtcars,
mapping: aes(x: "wt", y: "mpg", colour: "cyl"),
layers: (geom-point(size: 3pt),),
labels: labels(title: "Fuel Economy vs. Weight"),
width: 12cm,
height: 7cm,
)Stack two layers (geom-point + geom-smooth) and apply a theme, scales, and facets in one call.
#let d = ()
#for grp in ("a", "b") {
for i in range(0, 12) {
d.push((x: i, y: i * 0.5 + (if grp == "b" { 1 } else { 0 }) + calc.sin(i), grp: grp))
}
}
#plot(
data: d,
mapping: aes(x: "x", y: "y", colour: "grp"),
layers: (
geom-point(size: 2pt),
geom-smooth(method: "lm", se: false),
),
facet: facet-wrap("grp"),
theme: theme-minimal(),
labels: labels(title: "Per-Group Trend"),
width: 12cm,
height: 6cm,
)See also
aes, geom-point, coord-cartesian, facet-wrap, theme-grey, labels.