Skip to main content

annotate

Build a one-row annotation layer dispatching to a named geom.

Splits keyword arguments into two groups: those whose names match an aesthetic that the target geom reads become a single-row inline dataset plus an aesthetic mapping pointing each channel at the matching column, and the remainder are forwarded verbatim to the geom constructor as layer parameters. The resulting layer always has inherit-aes: false so it does not pick up the plot-level mapping.

Usage

annotate(
  geom,
  ..fields,
)

Parameters

Parameter Default Description
geom Geom name to dispatch to. One of "text", "point", "label", "segment", "rect", "vline", "hline", "abline".
clip Whether the annotation is clipped to the plot area. true (default) clips like any other layer; false lets the annotation overflow the panel, e.g., a corner inset or a mark placed past the axis limits. Unclipped annotations are drawn above every clipped layer regardless of their position in layers, so they read as deliberate overlays. A clip: false annotation is also exempt from the out-of-range pre-pass, so a position outside the scale limits is kept instead of dropped.
..fields Named arguments split between aesthetics and layer parameters. An aesthetic name is a key that the target geom reads, for example x, y, label, colour, nudge-x for "text", or xmin, xmax, ymin, ymax, fill for "rect". For "text", "label", and "typst", size is a layer parameter (the text size, a Typst length), not an aesthetic. stroke and linewidth never go to the inline row. They go to the geom as layer parameters, so a geom that does not take them, for example "text" or "typst", fails on them. Anything else (e.g., font or repel for "text", arrow for "segment") is forwarded to the geom constructor as a layer parameter, and the constructor fails for a name it does not know. A none or auto value on an aesthetic name is also forwarded as a layer parameter, so it reaches the geom as the disable / scale-resolve sentinel (e.g., fill: none draws an unfilled shape) instead of being stored as a data cell.

Returns

Layer dictionary consumed by plot.

Examples

Inline text plus a vertical reference line at the same x.

#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),
    annotate("text", x: 5, y: 4, label: "peak"),
    annotate("vline", xintercept: 5, colour: rgb("#cc0000")),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter chart with a red vertical reference line at x = 5 and a 'peak' text annotation positioned beside it.

Scatter chart with a red vertical reference line at x = 5 and a 'peak' text annotation positioned beside it.

Highlight a region with a translucent rectangle and a boxed label callout.

#let d = range(0, 10).map(i => (x: i, y: i * 0.5))
#plot(
  data: d,
  mapping: aes(x: "x", y: "y"),
  layers: (
    annotate(
      "rect",
      xmin: 3, xmax: 6, ymin: 1, ymax: 3.5,
      fill: rgb("#fff7e6"), alpha: 0.5,
    ),
    geom-point(size: 2pt),
    annotate("label", x: 4.5, y: 3.2, label: "window"),
  ),
  width: 10cm,
  height: 6cm,
)

Scatter chart with a pale yellow translucent rectangle highlighting the region x in 3-6, y in 1-3.5 and a boxed 'window' label inside.

Scatter chart with a pale yellow translucent rectangle highlighting the region x in 3-6, y in 1-3.5 and a boxed 'window' label inside.

See also

aes, geom-text, geom-point, geom-label, geom-segment, geom-rect, geom-vline, geom-hline, geom-abline.

Back to top