theme

Build a custom theme from per-element overrides.

Pass named arguments like axis-title: element-text(size: 12pt) or panel-grid: element-blank(). Each surface is stored as an element record; the renderer reads them via resolve-element with cascade surface → parent → defaults.

The table below is the full catalogue of accepted keys. Each row lists the key, its accepted type, the default applied when unset, and the parent it inherits from (root rows are at the top of an inheritance chain). Children with inherits for the default fall back through the parent chain until a default is found. Rows are grouped by family.

Key Type Default Parent
text element-text element-text(size: 9pt, weight: "regular") (root)
line element-line element-line(stroke: default-stroke-thickness) (root)
rect element-rect element-rect() (root)
plot-title element-text or element-typst element-text(size: (12 / 9) * 100%, weight: "bold") text
plot-subtitle element-text or element-typst element-text(size: 100%) text
plot-caption element-text or element-typst element-text(size: (8 / 9) * 100%) text
plot-tag element-text or element-typst element-text(size: (11 / 9) * 100%, weight: "bold") text
plot-background element-rect or element-blank element-rect() rect
axis-title element-text or element-typst element-text(size: 100%) text
axis-title-x element-text or element-typst inherits axis-title
axis-title-x-bottom element-text or element-typst inherits axis-title-x
axis-title-x-top element-text or element-typst inherits axis-title-x
axis-title-y element-text or element-typst inherits axis-title
axis-title-y-left element-text or element-typst inherits axis-title-y
axis-title-y-right element-text or element-typst inherits axis-title-y
axis-text element-text or element-typst element-text(size: (8 / 9) * 100%) text
axis-text-x element-text or element-typst inherits axis-text
axis-text-x-bottom element-text or element-typst inherits axis-text-x
axis-text-x-top element-text or element-typst inherits axis-text-x
axis-text-y element-text or element-typst inherits axis-text
axis-text-y-left element-text or element-typst inherits axis-text-y
axis-text-y-right element-text or element-typst inherits axis-text-y
axis-line element-line or element-blank element-line(stroke: 100%) line
axis-line-x element-line or element-blank inherits axis-line
axis-line-x-bottom element-line or element-blank inherits axis-line-x
axis-line-x-top element-line or element-blank inherits axis-line-x
axis-line-y element-line or element-blank inherits axis-line
axis-line-y-left element-line or element-blank inherits axis-line-y
axis-line-y-right element-line or element-blank inherits axis-line-y
axis-ticks element-line or element-blank element-line(stroke: 100%) line
axis-ticks-x element-line or element-blank inherits axis-ticks
axis-ticks-x-bottom element-line or element-blank inherits axis-ticks-x
axis-ticks-x-top element-line or element-blank inherits axis-ticks-x
axis-ticks-y element-line or element-blank inherits axis-ticks
axis-ticks-y-left element-line or element-blank inherits axis-ticks-y
axis-ticks-y-right element-line or element-blank inherits axis-ticks-y
tick-labels boolean true (root)
tick-length length 0.1cm (root)
tick-length-x length inherits tick-length
tick-length-x-bottom length inherits tick-length-x
tick-length-x-top length inherits tick-length-x
tick-length-y length inherits tick-length
tick-length-y-left length inherits tick-length-y
tick-length-y-right length inherits tick-length-y
panel-grid element-line or element-blank element-line(stroke: 100%) line
panel-grid-major element-line or element-blank inherits panel-grid
panel-grid-major-x element-line or element-blank inherits panel-grid-major
panel-grid-major-y element-line or element-blank inherits panel-grid-major
panel-grid-minor element-line or element-blank (stroke: 50%) panel-grid
panel-grid-minor-x element-line or element-blank inherits panel-grid-minor
panel-grid-minor-y element-line or element-blank inherits panel-grid-minor
panel-background element-rect or element-blank element-rect() rect
legend-title element-text or element-typst element-text(size: (8 / 9) * 100%) text
legend-text element-text or element-typst element-text(size: (8 / 9) * 100%) text
legend-ticks element-line or element-blank element-line(stroke: (0.3 / 0.5) * 100%) line
legend-background element-rect or element-blank element-rect() rect
legend-bar element-rect or element-blank element-rect(stroke: (0.2 / 0.5) * 100%) rect
legend-key length 0.24cm (root)
legend-position side, alignment, or dict auto (root)
strip-text element-text or element-typst element-text(size: (8 / 9) * 100%) text
strip-background element-rect or element-blank element-rect() rect
geom element-geom element-geom() (root)
ink colour black (root)
paper colour white (root)
accent colour rgb("#3366FF") (root)

Usage

theme(
  ..fields,
)

Parameters

Parameter Default Description
..fields Named per-element overrides; see the description above for the full catalogue of structured and flat keys.

Returns

Theme dictionary consumed by plot.

Examples

Custom panel and grid colours via structured element records.

#let d = range(0, 10).map(i => (x: i, y: i * 0.5))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y"),
  layers: (geom-point(size: 2pt),),
  theme: theme(
    text: element-text(colour: rgb("#2c3e50")),
    panel-background: element-rect(fill: rgb("#f7f0e7")),
    panel-grid: element-line(colour: rgb("#d9cfbf")),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter plot of y against x on a custom theme with navy text, a warm cream panel and pale stone gridlines via element records.

Scatter plot of y against x on a custom theme with navy text, a warm cream panel and pale stone gridlines via element records.

Hide elements entirely with element-blank, useful for very minimalist figures.

#let d = range(0, 10).map(i => (x: i, y: i * 0.5))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y"),
  layers: (geom-point(size: 2pt),),
  theme: theme(
    panel-grid: element-blank(),
    axis-line: element-blank(),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter plot of y against x with the panel grid and axis lines hidden via element-blank for a stripped-back minimalist figure.

Scatter plot of y against x with the panel grid and axis lines hidden via element-blank for a stripped-back minimalist figure.

Tweak the scalar fields: bigger ticks, hidden tick labels, and a tinted panel background padded via element-rect’s inset (inner padding).

#let d = range(0, 10).map(i => (x: i, y: i * 0.5))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y"),
  layers: (geom-point(size: 2pt),),
  labels: labels(y: "Cumulative Response (Per Protocol)"),
  theme: theme(
    tick-length: 0.25cm,
    tick-labels: false,
    panel-background: element-rect(
      fill: rgb("#f7f0e7"),
      inset: margin(top: 0.4cm, right: 0.4cm, bottom: 0.4cm, left: 0.4cm),
    ),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter plot of cumulative response against x with longer 0.25cm ticks, hidden tick labels and a panel-background rect grown 0.4cm on every side via element-rect inset (inner padding).

Scatter plot of cumulative response against x with longer 0.25cm ticks, hidden tick labels and a panel-background rect grown 0.4cm on every side via element-rect inset (inner padding).

Move every legend at once with the legend-position scalar; it accepts the same values as guide-legend(position:) and any explicit guides placement overrides it per aesthetic.

#let d = range(0, 10).map(i => (x: i, y: i * 0.5, g: if calc.even(i) { "a" } else { "b" }))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y", colour: "g"),
  layers: (geom-point(size: 2pt),),
  theme: theme(legend-position: "bottom"),
  width: 10cm,
  height: 6cm,
)

Scatter plot of y against x coloured by group with the colour legend placed below the panel via the theme legend-position field.

Scatter plot of y against x coloured by group with the colour legend placed below the panel via the theme legend-position field.

Set fonts per surface: a base text font every text surface inherits, a distinct font for the plot title, and an element-geom font role for the text-drawing geoms.

#let d = range(0, 6).map(i => (x: i, y: i * 0.5))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y"),
  layers: (geom-point(size: 2pt), geom-text(mapping: aes(label: "x"))),
  labels: labels(title: "Fonts", x: "X", y: "Y"),
  theme: theme(
    text: element-text(font: "New Computer Modern"),
    plot-title: element-text(font: "DejaVu Sans Mono"),
    geom: element-geom(font: "New Computer Modern"),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter plot of y against x with point labels, the plot title set in DejaVu Sans Mono and every other text surface plus the geom-text labels in New Computer Modern via theme fonts.

Scatter plot of y against x with point labels, the plot title set in DejaVu Sans Mono and every other text surface plus the geom-text labels in New Computer Modern via theme fonts.

See also

theme-grey, theme-minimal, theme-classic, theme-void, element-text, element-line, element-rect, element-blank, margin.

Back to top