Changelog
Version history.
0
0.6
0.6.0 (2026-07-28)
Breaking changes
- feat!: axis ticks are themed through the single
axis-ticksfamily: the newelement-tick(colour:, stroke:, length:)carries the mark length, sotick-length(and its per-axis and per-side variants) is removed, andtick-labelsis removed in favour of hiding labels per side withaxis-text: element-blank().axis-ticks: element-blank()is now the one switch that turns marks off, reserving no depth either. (#150GitHub) - feat!: the summary-dispatch kernel
summarise(name, values)leaves the public API (renamed to the internal_apply-summary), freeing thesummarisename for the new wrangle verb; thefun:argument ofstat-summaryandstat-summary-bin(a name string or callable) is unchanged. (#198GitHub)
Changes
- feat: automatic continuous breaks come from the extended Wilkinson search (Talbot, Lin, and Hanrahan 2010), which scores candidate tick sequences on simplicity, coverage of the data, and tick count, replacing the fixed 1/2/5 ladder on axes and continuous guides; most plots gain rounder ticks that sit closer to the data.
breaks-extended(n:)exposes it for a different target count. (#217GitHub) - feat:
breaks:andminor-breaks:on a continuous scale accept a closure called with the vector of values the scale trained on (once per panel, so free-scale facets each get their own) and returning the tick positions; unlike an explicit array, closure breaks are clipped to the trained domain rather than widening it. (#216GitHub) - feat:
breaks-width(width, offset:),breaks-pretty(n:), andbreaks-quantile(probs:)build that closure for the common placements: a fixed step, round positions at a target count, and sample quantiles of the data. (#216GitHub) - feat:
summarise(data, ..aggregations, by:)andcount(data, ..cols, sort:)bring grouped aggregation to the row-store data model: one output row per group, namedrows => valueaggregation closures, first-appearance group order, column-store input accepted, and output that feeds#plotdirectly. (#198GitHub) - feat:
as-numeric(data, col, na:)takes a list of sentinel values (a bare value is accepted); cells equal to a sentinel (string cells compared trimmed) becomenonebefore parsing, so missing-value placeholders such as"NA"or"-99"do not survive as spurious numbers. (#198GitHub) - feat: column/row selection verbs
select(data, ..names),rename(data, ..renames),relocate(data, ..cols, before:, after:),drop-na(data, ..cols),distinct(data, ..cols), andslice-max/slice-min(data, col, n: 1, by:)reshape, dedup, and rank a row-store (non-numeric or missing values sort last when ranking), accept column-store input, and feed#plotdirectly. (#198GitHub) - feat: reshaping verbs
pivot-longer(data, cols, names-to:, values-to:)andpivot-wider(data, names-from:, values-from:)melt columns into a name/value pair and spread them back (round-tripping modulo column order), filling absent combinations withnone, failing on an ambiguous duplicate spread, and carrying theas-factortag on surviving identifier columns. (#198GitHub) - feat: join and bind verbs
left-join/inner-join/full-join/semi-join/anti-join(x, y, by:)combine two row-stores on shared key columns (a natural join on the common columns whenby: none, a non-key column present in both is an error), andbind-rows(..datasets)/bind-cols(..datasets)stack or glue datasets, unioning columns withnone-fill or zipping them by row position. (#198GitHub) - feat: the bundled
mpgdataset carries adrvcolumn ("4","f","r"), so drive train can be faceted, coloured, or grouped on without substitutingcyl. (#226GitHub) - feat: minor tick marks are themable through
axis-ticks-minorand its per-axis variants, replacing the hardcoded half-length, major-stroke sub-decade ticks drawn byguide-axis-logticks(); they inherit the major tick record, so the default rendering is unchanged. (#150GitHub) - fix: a numeric
nudge-x/nudge-yongeom-text,geom-label, andgeom-typstno longer fails the compile when a positional scale is discrete; the offset shifts in level units there, matchingposition-nudge, and a nudge on the continuous axis of such a plot now applies instead of erroring. (#225GitHub) - fix:
dup-axis(breaks:, labels:)andsec-axis(breaks:, labels:)are honoured; the secondary axis drew the primary grid with the primary formatting whatever these were set to. (#216GitHub) - fix: a continuous scale trained on whole numbers only (years, counts, epoch days) keeps whole automatic breaks on axes and on continuous legends, so a narrow range such as 2020 to 2023 no longer labels half-steps. (#213GitHub)
- fix: legend entry labels, vertical colourbar tick labels, and y-axis tick labels centre on the cap-height/baseline band instead of the glyph bounds, so a label carrying a descender (
Chinstrap) no longer sits higher than one without (Adelie). (#208GitHub, #209GitHub) - docs: footer links are legible in light mode (they were painted the page colour), the footer top rule reads in dark mode instead of being 8% black on dark paper, and the copy-to-clipboard button no longer hangs past the bottom border of a one-line code block. (#222GitHub)
- docs: the theming guide gains a “Ticks and their labels” section showing
element-tick, ratio lengths, minor marks, and per-side label hiding. (#219GitHub) - docs: reference pages link every cross-reference instead of printing a bare
@geom-linewhen the reference closes a parenthetical, and links no longer run into the preceding word or comma. (#215GitHub) - docs: every
scale-*reference page lists the keys its..argsaccepts with their type, accepted values, and default (includingoob, previously undocumented), instead of naming a few of them in prose. (#214GitHub) - docs: in the collapsed navbar, the colour-scheme toggle and the search button group at the right edge, separated by the same gap as the rest of the navbar-right controls, and the brand centres, instead of the toggle sitting beside the brand with the search alone at the far right. (#210GitHub)
- docs: the navbar GitHub icon becomes a widget showing live star and fork counts and a project menu (repository, issues, pull requests, releases, star, fork, Typst Universe, sponsor), replacing the separate Typst Universe, source-code, releases, and sponsor links; the version switcher, GitHub widget, search button, and colour-scheme toggle share one pill button style. (#205GitHub)
- docs: add a “Wrangling data” guide walking a dataset from coercion through grouped aggregation, reshaping, and joining into
#plot, with guidance on when native Typst suffices. (#198GitHub) - docs: the News page and the changelog link the Gribouille 0.6 release announcement. (#227GitHub)
- docs: the stable site is rendered wholly from the release tag instead of taking its pages from
mainagainst a pinnedsrc, so each site documents the API it ships with, and a documentation fix now reaches the stable site at the next release rather than immediately. (336b698GitHub) - docs: the navbar is dark in both light and dark schemes (matching the other project sites); add scheme-aware scrollbars, an accessible skip link and focus outline, and fix the tabset panel border that was indistinguishable from the background in dark mode. (d21e005GitHub)
- docs: in the collapsed navbar, opening a menu (e.g., Guides) overlays on top instead of growing the navbar and pushing the other items down, matching the GitHub widget menu. (930fb21GitHub)
0.5
0.5.0 (2026-07-13)
Breaking changes
- feat!:
linetypeongeom-segment,geom-curve,geom-spoke,geom-errorbar,geom-errorbarh,geom-linerange, andgeom-pointrangedefaults toautoand honours a mapped linetype scale instead of pinning"solid". (#169GitHub) - feat!: every constructor dict stores its concrete type under a single
name:key; the per-family fieldsgeom:(layers),coord:,facet:,family:(scale stubs),labeller:, andkey:(draw keys) are renamed,guide-custom()returnskind: "guide", name: "custom", andposition-fill()/position-identity()/position-stack()carry an explicitparams: (:). Only code that pattern-matches the returned dicts is affected. (#168GitHub) - feat!: the per-aesthetic
scale-*constructors collapse into an aesthetic-agnostic set keyed throughscales(); the aesthetic now comes from the key, soscale-colour-viridis-d()becomesscales(colour: scale-viridis-d())andscale-x-log10()becomesscales(x: scale-log10()).plot(scales:)takes only thescales()dictionary (no positional array), andexpand-limits()returns an aesthetic-keyed dictionary. (#158GitHub)
Changes
- feat:
geom-beeswarm,position-jitter, andposition-jitterdodgeswarm or jitter a discrete (categorical) x directly, likegeom-violin;as-factoris no longer required and is only needed to force a numeric column onto a discrete axis. Level positions now follow the sorted axis domain, so the swarm aligns regardless of row order. (#196GitHub) - feat:
facet-wrapandfacet-gridgain agutterargument and honour a newtheme(panel-spacing:)default (a length for both axes or a(x:, y:)dictionary), replacing the fixed 0.4/0.3cm panel gaps with a shared 0.5cm default. (#191GitHub) - feat:
composegutteraccepts a(x:, y:)dictionary for independent column and row spacing alongside the existing scalar length. (#191GitHub) - feat:
stat-waffleturns per-group counts (one per row, or the roundedweightsum) into unit cells on an integer grid, column-major from the bottom-left with groups tiling consecutive runs; render waffle charts withgeom-tile. (#189GitHub) - feat:
stat-connectgainsconnection: "sigmoid", a logistic S-curve connector rescaled through both observations withsmoothandncontrol; paired withgeom-lineand a reversed y scale it draws bump charts. (#188GitHub) - feat:
position-stackgains streamgraph baseline offsets:offset: "silhouette"centres each stack on zero andoffset: "wiggle"uses the Byron-Wattenberg wiggle-minimising baseline, turning stackedgeom-areainto a streamgraph. (#187GitHub) - feat:
stat-differenceshades the band between two series by which one is on top: exact linear crossovers are inserted as shared vertices so ribbon segments meet cleanly, and each run carries a_signlevel (names vialevels:) forfill: after-stat("_sign"). (#186GitHub) - feat: fills accept native Typst
tilingpaints, both as fixedfill:values and throughscale-manual(values:), with legend swatches rendering the patterns; per-row alpha and seam sealing skip non-colour paints. (#182GitHub) - feat:
position-beeswarmandgeom-beeswarmarrange overplotted points into a deterministic density-shaped swarm (van der Corput walk scaled by each point’s kernel density), a reproducible alternative toposition-jitter. (#181GitHub) - feat:
geom-density-ridgesandstat-density-ridgesdraw overlapping ridgeline plots from raw observations: one Gaussian-KDE ridge per y bucket with heights normalised across buckets, ascaleparameter in y-level units, and a newheightaesthetic channel. (#180GitHub) - feat:
geom-density-2d/geom-density-2d-filledand their stats trace iso-lines or shade iso-bands of a native 2D Gaussian kernel density estimate of the raw(x, y)sample, with per-axis bandwidth and grid control. (#178GitHub) - feat:
geom-smooth/stat-smoothgainmethod: "loess"withspananddegreecontrol: native tricube-weighted local polynomial fits with a pointwise confidence band onn − trace(L)degrees of freedom. (#177GitHub) - feat:
geom-violinandstat-ydensitydraw mirrored per-bucket density silhouettes withscale: "area"/"count"/"width"normalisation,trimcontrol, and dodge support, sharing the native Gaussian KDE core withstat-density. (#176GitHub) - feat:
geom-densityandstat-densitybring native 1D kernel density estimation: Gaussian kernels evaluated directly on ann-point grid, Silverman (bw.nrd0) bandwidth withadjustandtrimcontrol, weight support, and_density/_count/_scaled/_nafter-stat columns. (#175GitHub) - feat: every geom exposes
key:(legend glyph override) and, where meaningful,stat:andposition:; stat-backed geoms takestat: autoto build their default stat from the geom parameters. (#169GitHub) - feat: a keyed
scales()constructor, mirroringguides(), binds scale overrides to aesthetics as named arguments (e.g.,scales(x: scale-continuous(), colour: scale-viridis-d())) instead of a positional array. (#157GitHub) - feat: an installable Agent Skill teaches coding agents to author Gribouille plots, confirming every argument against the site’s
.llms.mdreference; the repository doubles as a Claude Code plugin marketplace, so the skill installs via/plugin installornpx skills add. (#154GitHub) - feat: geom and theme-element
stroke:accept the native Typst1.3pt + accentform, writing thickness and paint together; an explicitcolour:still wins over the embedded paint. (#153GitHub) - fix: support explicit
as-factor()onxforgeom-violin,geom-boxplot, and other per-group stats when a grouping aesthetic reuses the same column. (#195GitHub) - fix:
geom-densitywith a mappedfillaesthetic shades the curves instead of rendering a blank panel; the default is unfilled through a fill role rather than a hardfill: none. (#192GitHub) - fix: non-identity positions (
jitter,beeswarm) over anas-factorpositional column that is also mapped tocolour/fillnow draw the mapped scale colours instead of the default; the 1-indexed positions go to a synthetic column so the source column keeps its levels. (#192GitHub) - fix: pre-stat grouping skips late-binding markers without a source column (e.g.,
fill: after-stat("_sign"),colour: after-stat("_level")) instead of crashing on the marker dict; the stat-output column groups the rows once the stat has run. (#186GitHub) - fix:
annotateforwards anoneorautovalue on an aesthetic keyword (e.g.,annotate("rect", fill: none)) to the geom as a layer parameter instead of storing it as a data cell, so the disable / scale-resolve sentinel applies and the shape is drawn unfilled. (#183GitHub) - fix: fill opacity defaults to 1 on
geom-area,geom-ribbon,geom-polygon,geom-ellipse, andgeom-markinstead of an implicit 0.3-0.6 translucency; explicitalpha:values and mapped alpha aesthetics are unaffected. (#179GitHub) - fix: abutting opaque fills (tiles, hexes, stacked bars and areas, iso-band cells) are stroked with their own fill colour, removing the hairline background seams that antialiasing bled through between adjacent shapes. (#178GitHub)
- fix: stat-quantile replaces the O(n³) pair enumeration with an exact O(n² log n) breakpoint search, scaling geom-quantile to thousands of rows with identical fits on unique optima. (#174GitHub)
- fix: an unknown scale-* constructor argument now fails at scales() binding with the valid keys for that scale and aesthetic, and stray positional arguments are rejected instead of ignored. (#172GitHub)
- fix: an unknown
stat, scaletransform, oroobname now fails with a clear error instead of silently rendering as identity or dropping rows. (#162GitHub) - fix:
theme()rejects unknown or misspelled element keys and positional arguments instead of storing a key the renderer never reads. (#162GitHub) - fix:
aes()rejects unknown aesthetic names, such as the US spellingcolor, with a message listing the valid channels. (#162GitHub) - fix:
plot()validates themapping,layers, andcoordarguments up front with a named error instead of a cryptic renderer failure. (#162GitHub) - fix: data-ingestion and
from-themepath errors now show the offending value. (#162GitHub) - fix: mapping an aesthetic or a facet variable to a column absent from the data now fails with a clear error naming the aesthetic, the unknown column, and the available columns, instead of rendering a misleading all-
noneplot. (#156GitHub) - fix: numeric values on a discrete scale (a polygon vertex set between level centres, a jittered point) are kept as fractional level positions instead of being dropped when the scale carries explicit
limits. (#151GitHub) - docs: the published Typst Universe README drops the repo-only “Ask DeepWiki” badge and now keeps the “AI assistants” section. (#194GitHub)
- docs: add streamgraph, bump chart, difference band, and waffle chart gallery examples. (#193GitHub)
- docs: a Recipes guide shows chart types and effects built by composing layers and native Typst, with no dedicated geom: lollipop and dumbbell charts, group highlighting, zoom insets, marginal panels, irregular grid layouts, and trend-line casing. (#185GitHub)
- docs: the agent skill covers the current API: the aesthetic-agnostic
scales()constructors, the density and pattern-fill idioms, and a symbol inventory regenerated fromlib.typand checked in CI. (#184GitHub) - docs: each scale constructor reference page carries a runnable example in the keyed
scales()form. (#160GitHub) - docs: an AI Assistants guide explains how to use Gribouille with large language models through the
llms.txtmachine-readable documentation and the installable skill. (#154GitHub) - docs: a Benchmarks guide measures how compile time and output size grow with element count, drawn from a committed dataset with Gribouille itself, and shows where per-row geoms become impractical for large data. (#149GitHub)
0.4
0.4.1 (2026-06-23)
- fix:
position: "dodge"now shifts point-based geoms (text, label, point, linerange, etc.) on continuous x-axes by inferring the slot width from the minimum gap between unique positions. (#145GitHub) - fix: string values such as
"0"are no longer inferred as numeric for scale type; only Typstint/floatvalues produce a continuous scale. CSV users relying on string-numeric x-columns being treated as continuous must callas-numeric(data, "col")first. (#145GitHub) - docs: the News page links the Gribouille 0.4 release announcement and shows a featured image for each release. (#141GitHub)
0.4.0 (2026-06-22)
Breaking changes
- feat!:
coord-cartesian()andcoord-radial()takeclipas a boolean (true/false) instead of the strings"on"/"off". (#134GitHub) - feat!:
labs()is renamed tolabels(), and theplot()/compose()labs:argument tolabels:; there is nolabsalias. (#131GitHub) - feat!:
coord-cartesian(),stat-function(), andgeom-function()rename thexlim/ylimarguments tox-limits/y-limits. (#131GitHub) - feat!: the
col-mix()colour helper is renamed tocolour-mix(), with argumentscolour1/colour2. (#131GitHub) - feat!:
geom-text,geom-label, andgeom-typstdrop thedx/dyparameters; offsets now use thenudge-x/nudge-yaesthetics, where a number shifts in data units and a Typst length shifts in canvas units. (#131GitHub)
Changes
- feat: continuous scale
limitsandgeom-ablineintercepts accept ISO-8601 date/datetime/time strings under a temporal scale, completing the temporal-string contract. (#137GitHub) - feat:
geom-vline/geom-hlineintercepts and continuous scalebreaksaccept ISO-8601 date/datetime/time strings under a temporal scale, matching how geom data is already parsed. (#136GitHub) - feat:
geom-area()accepts adirectionparameter ("hv"or"vh") that steps the filled top edge likegeom-step();none(default) keeps the smooth area. (#135GitHub) - feat:
element-text()/element-typst()angleis now honoured on axis titles, strip text, and legend title and entry labels (previously only tick labels and the plot title, subtitle, and caption); axis titles default to 0deg (x) / 90deg (y) and reserve the correct space at any angle. (#134GitHub) - feat:
geom-text(),geom-label(), andgeom-typst()accept anangleparameter (a Typst angle, default0deg) rotating each label. (#134GitHub) - feat: every aesthetic key can be pinned as a constant directly on any geom, e.g.,
geom-label(nudge-x: 0.5), not only throughaes(); declared parameters still bind first and unknown or positional arguments are rejected. (#133GitHub) - feat: scale
expandacceptsautoon one side, e.g.,expand: (0%, auto), keeping the per-scale default for that side. (#132GitHub) - feat:
geom-vline,geom-hline, andgeom-ablineread their intercept channels fromaes(); bindingxintercept/yintercept/slope/intercepttogether withdatadraws one line per row with per-rowcolour/alpha/linewidth/linetype, and a mappedxintercept/yinterceptextends the panel to keep the lines in view; the scalar/array parameter still draws shared lines when nothing is mapped. (#129GitHub) - feat: a font set in
theme(text: ...)now reaches literal-glyph point markers (e.g.,shape: sym.star) for both plot markers and legend keys, instead of falling back to the document font. (#126GitHub) - feat:
geom-text,geom-label, andgeom-typstaccept afont:parameter;autouses the themetextfont, then the document font. (#126GitHub) - feat: panel gridlines split into a ggplot2-style cascade,
panel-grid->panel-grid-major/panel-grid-minor->-x/-y, so X/Y and major/minor lines are styled independently; minor defaults to half the major weight in the same colour and a blankpanel-gridblanks both weights. (#125GitHub) - feat: continuous axes draw minor gridlines (visible by default): midpoints between majors for linear/sqrt/reverse and sub-decade lines for log10;
scale-*-continuous(and log10/sqrt/reverse) acceptminor-breaksandn-minorto position them. (#125GitHub) - feat: the
legend-positiontheme entry sets a global side for every legend (theme(legend-position: "bottom"), also viatheme-sub-legend(position:)), accepting the same values asguide-legend(position:); any explicitguides()placement still wins. (#123GitHub) - feat: discrete (swatch) legend key glyphs are resizable via
guide-legend(key-size: <length>)per legend or thelegend-keytheme entry for every swatch legend; the row spacing and label offset grow with the glyph so enlarged keys do not overlap. (#122GitHub) - feat: the
shapeaesthetic accepts any character as the marker symbol; a value outside the eight built-in keywords renders as a literal glyph, so letters or emoji work as markers acrossscale-shape,scale-shape-manual,scale-shape-identity,scale-shape-binned, thegeom-point(shape: ...)pin, and legend keys. (#120GitHub) - feat: scale
limitsacceptautoon one side, e.g.,limits: (auto, 60), keeping the trained bound for the other side. (#116GitHub) - feat: binned position scales (
scale-x-binned/scale-y-binned) acceptbreaksas bin edges; ticks sit at interval midpoints andn-breaksis ignored whenbreaksis set. (#116GitHub) - feat: binned colour, fill, shape, linetype, size, linewidth, stroke, and alpha scales accept
breaksas bin edges; colour, fill, shape, and linetype bin per row by the edges, the others bin their legend. (#116GitHub) - feat: bundled datasets (
penguins,economics,mpg) ship as row-store arrays, sopenguins.filter(...)and.map(...)work directly;plot()still accepts them. (#116GitHub) - fix: scalar and Typst-length
nudge-x/nudge-yvalues now apply togeom-text/geom-label/geom-typst(previously a silent no-op). (#131GitHub) - fix: setting the base
line/rectstroke intheme()now cascades to every line and rect surface (panel grid, axis line, ticks, legend ticks, legend bar);element-line/element-rectstrokeaccepts a ratio (e.g.,80%) to scale the parent surface thickness, while an absolute length still pins a surface outright. (#124GitHub) - fix: setting the base
textsize intheme()now cascades to every text surface (axis titles, tick labels, legend, strip, plot title);element-text/element-typstsizeaccepts a ratio (e.g.,80%) to scale the parent surface size, while an absolute length still pins a surface outright. (#121GitHub) - fix:
position: "dodge"now shiftsgeom-text/geom-label/geom-typst,geom-point,geom-line/geom-path/geom-step,geom-pointrange, andgeom-linerangemarks side by side, matching the dodged bars instead of staying on the category centre. (#119GitHub) - fix:
theme-grey()matches ggplot2theme_grey()with white grid lines and no axis lines. (#116GitHub) - fix: explicit continuous
breaksexpand the axis range so requested ticks stay visible, unless a side is pinned by an explicitlimit. (#116GitHub) - docs: a News page lists the release announcement posts, and each changelog version links to its announcement. (#139GitHub)
0.3
0.3.0 (2026-06-14)
Breaking changes
- feat!:
compose()panels are now built with the newdefer()helper (defer(plot, ...), ordefer(compose, ...)to nest), replacingplot(..., defer: true); panels omit their ownwidth/heightand the composition sizes each cell. (#81GitHub)
Changes
- feat: the published package now ships Tinymist-friendly docstrings; hovering a gribouille function in an editor shows formatted parameters, returns, and examples instead of the raw
@-tag comments. Variadic sinks list their accepted keys:guides()its aesthetics, andtheme()and the theme presets their element surfaces. (#108GitHub) - feat: under
coord-radial,guides(theta: none)hides the angular axis (arc, minor ticks, and tick labels) andguides(r: none)hides the radial tick labels; the spokes and circles stay. Also fixesguides(theta: none)previously adding a theta arc instead of hiding the axis. (#106GitHub) - feat:
guides(x: none)/guides(y: none)hide that axis’s tick marks and tick labels (and any log minor ticks) and reclaim the freed space; the axis line, grid, and title stay (remove the title withlabs(x: none)). (#105GitHub) - feat:
guides()acceptsnoneto hide a guide andautofor the default;guides(default: none)hides every legend without its own override, and any other non-guide value fails with a clear message. Replaces the removedguide-none()(passnoneinstead). (#104GitHub) - feat:
annotate()gains aclipargument (defaulttrue); setclip: falseto let an annotation overflow the panel, e.g., a corner inset or a mark placed past the axis limits. (#93GitHub) - feat:
compose()acceptstheme:; an explicit theme styles the composition chrome (title, hoisted legend, panel tags) and propagates into panels with no theme of their own, otherwise a theme shared by every panel is used. (#82GitHub) - feat:
geom-area()defaults tostat: "align"andposition: "stack"; groups with mismatched x values are automatically resampled onto a shared grid and stacked without requiring explicitstat: stat-align(). (#77GitHub) - fix:
stat-bin-2dandstat-bin-hex_densityis now the cell’s fraction of the total count (count / sum(count)), matching ggplot2, instead of an undocumented count-per-cell-area value. (#109GitHub) - fix: data outside a
sqrtorlog10transform’s domain (negative, or zero/negative forlog10) now panics with a clear scale message instead of a raw Typst error, and the sqrt inverse clamps padded view bounds at zero so sqrt axes stay monotone and show the0break. (#109GitHub) - fix: a horizontal legend (
position: "top"/"bottom") withguide-legend(align: center)/align: rightnow centres or right-justifies its key graphic (colourbar bar, key row, or size band) under the title, instead of leaving the graphic pinned at the left edge while the title moved; a centred colourbar also keeps its end labels inside the legend block. (#103GitHub) - fix: the theme
legend-backgroundnow inherits the baserectelement like every other*-backgroundsurface, sotheme(rect: ...)cascades to it instead of being ignored. (#101GitHub) - fix:
guide-legend(nrow:)/guide-legend(ncolumn:)now lay a continuous size legend (scale-size-*) out in a grid, like the discrete swatch legend, instead of being ignored; a continuous colourbar stays a single bar and ignores them. (#99GitHub) - fix:
guide-legend(align:)now also aligns the legend title (not just the entry labels), and a string such asalign: "left"fails with a clear message instead of a vague panic or being silently ignored;alignis a Typst alignment (left,center,right). (#98GitHub) - fix:
annotate(clip: false)placed outside the scalelimitsnow draws instead of being dropped by the out-of-range pre-pass, so a corner inset or a mark parked past the axis range is kept. (#97GitHub) - fix: a left/right legend that would overrun the caption, or a hoisted
compose()legend that leaves no room for the panels, now fails with a clear layout hint instead of silently overprinting. (#96GitHub) - fix: continuous
scale-size-*legends reserve row height and stride for the resolved key glyph, so a wide sizerangeno longer overlaps the keys and labels. (#95GitHub) - fix: the out-of-range filter respects scale
expand, keeping points and annotations that sit inside the expansion headroom instead of dropping them; reversedlimits(a flipped axis) no longer drop every row. (#92GitHub) - fix:
geom-linerange()honours itsalphaparameter; the line was previously always drawn fully opaque. (#85GitHub) - fix:
geom-area(position: "stack")now stacks bands correctly; each polygon’s lower edge sits at the cumulated top of the group below rather than always closing aty = 0. (#77GitHub) - fix:
stat-align()expands its shared grid by a small offset on either side of every breakpoint, so a group that starts or ends mid-range steps cleanly down to the baseline instead of leaving a wedge below the neighbouring group. (#77GitHub) - docs: the theming guide notes relative (
%) versus absolute text sizing, andelement-textgains an example contrasting the two. (#121GitHub) - docs: the
guides()reference lists each accepted key (colour,fill,…) as a sub-list under the..argsparameter, sharing one description template. (#108GitHub) - docs: reference pages for forwarding functions such as the
scale-*colour wrappers now list their real parameters instead of an opaque..argsrow, and a mixed signature likeannotate(geom, ..fields)also listsclip. (#102GitHub) - docs: the
theme()reference table now lists every theme key, addingplot-tag,legend-ticks,legend-background,legend-bar, andgeom. (#100GitHub)
0.2
0.2.1 (2026-06-03)
- feat:
compose()gainsalign-panels(defaultfalse); whentrue, panels share margins grid-wise (left/right per column, top/bottom per row) so their plot areas line up across rows and columns, likepatchwork/cowplotpanel alignment. (#71GitHub) - fix:
compose()panel tags (tag-levels) reserve their own band so they no longer overlap the panel content. (#70GitHub) - fix:
geom-segment/geom-curve/geom-ribbon/geom-arearender on discrete scales instead of silently drawing nothing. (#69GitHub)
0.2.0 (2026-06-01)
- feat: a layer’s
dataaccepts a function applied to the plot data, returning that layer’s frame (e.g.,geom-point(data: rows => rows.filter(...))), for subsetting or per-layer transforms without a separate dataset. (#62GitHub) - feat:
facet-grid(scales:)supports free scales ("free_x"frees x per column,"free_y"frees y per row,"free"both); non-positional scales stay shared and panels keep equal size. (#60GitHub) - feat: legend entry labels honour the
legend-texttextalign, andguide-legend()gains analignargument; horizontal legends default to centred labels, vertical to left. (#34GitHub) - feat:
compose()acceptsdefer: trueto return a spec usable as a panel of anothercompose, enabling nested compositions;tag-levelsaccepts a per-depth array (withtag-sep) so nested panels continue the numbering (e.g.,B.1,B.2). (#24GitHub) - feat:
compose()can number panels with a tag pattern (tag-levels"A"/"a"/"1"/"I"/"i", plustag-prefix/tag-suffix/tag-corner), styled by the newplot-tagtheme element. (#23GitHub) - feat:
compose()accepts composition-levellabs(title/subtitle/caption) andalt, and now controls the collected legend’s side throughguides(e.g.,guides(default: guide-legend(position: "bottom"))); theguides-placementparameter is removed. (#22GitHub) - feat:
guides()accepts adefaultentry that sets fallback guide options (such as the legend side) inherited by every aesthetic without its own override, in bothplot()andcompose();guide-legend’spositionnow defaults toautoand inherits from it. (#21GitHub) - feat:
compose()gainswidth/height(filling a bounded container by default) and relativewidths/heightsto set panel proportions relative to one another. (#20GitHub) - feat:
element-text()/element-typst()gain analignparameter setting per-surface text alignment, independent of the container; title and subtitle default left, caption right, axis titles and strip text centred. (#13GitHub) - feat:
labs()fields default toauto; passnoneto suppress an axis or legend title and reclaim the space it reserved. (#12GitHub) - feat:
element-blank()on a text surface (axis, plot, or legend title) collapses the space the text would reserve. (#12GitHub) - feat:
width/heightacceptautoto fill the available space of a bounded container. (#10GitHub) - fix: a standalone plot no longer reserves a fixed empty margin on its top and right edges, letting the panel fill that space. (c9d53acGitHub)
- fix: a plot with no x-axis title reclaims the empty space the title would have reserved below the panel, matching the y-axis side. (#61GitHub)
- fix:
element-text(angle:)/element-typst(angle:)rotate axis tick labels (seeding theguide-axis(angle:)default) and the plot title, subtitle, and caption, instead of being ignored. (#59GitHub) - fix:
labs(tag:)draws the figure tag above the title on a standalone plot, styled by theplot-tagtheme element, instead of being ignored. (#58GitHub) - fix:
labs(alt:)fills in the figure’s accessibility alt text whenplot(alt:)is unset, instead of being stored and ignored. (#57GitHub) - fix:
geom-qq()/geom-qq-line()honour thedistributionargument (uniform/exponential) instead of always plotting against the normal reference. (#56GitHub) - fix: the
fontset onelement-text/element-typst/element-geomis applied to every text surface and to the text-drawing geoms, inheriting the basetextfont when unset. (#54GitHub) - fix: a
stage/after-scalechannel now trains its scale on the marker’s source column, so the closure receives the channel’s scale-resolved value as documented. (#52GitHub) - fix: grouped geoms (e.g.,
geom-smooth) no longer panic when a grouping aesthetic is mapped viaafter-scaleorstage. (#51GitHub) - fix: facet-grid legends reserve space for a secondary x-axis so a top legend no longer overlaps its ticks. (#46GitHub)
- fix:
geom-errorbar()/geom-errorbarh()/geom-rug()resolve anafter-scale/stagecolour mapping instead of panicking. (#45GitHub) - fix: continuous legends fall back to computed breaks when every user-supplied break falls outside the domain. (#44GitHub)
- fix:
coord-cartesian(xlim:/ylim:)zooms continuous axes instead of being ignored. (#43GitHub) - fix:
coord-flip(reverse: true)preserves alog10/sqrtaxis transform instead of overwriting it. (#42GitHub) - fix:
geom-col()on a continuous x with a single distinct value no longer panics when inferring the bar width. (#41GitHub) - fix:
log10/sqrtscales validate userlimitsand report a clear error for non-positive bounds. (#40GitHub) - fix:
geom-smooth()honours thelevelargument when sizing the confidence band instead of always using 95%. (#39GitHub) - fix: binning geoms reject a non-positive
binswith a clear error instead of dividing by zero. (#38GitHub) - fix: contour stats skip incomplete cells when the
(x, y, z)grid is sparse instead of panicking. (#37GitHub) - fix:
scale-*-manual()with an emptyvaluesarray reports a clear error instead of an opaque divide-by-zero. (#36GitHub) - fix: number formatters carry a fraction that rounds up to a whole unit (e.g.,
0.9999995no longer renders as0.1), andformat-scientifickeeps its mantissa in[1, 10). (#35GitHub) - fix: legend guides reserve space for multi-line labels, measuring the resolved custom
labels:for both width and line count across swatch, size-ladder, and colourbar guides, so two-line content no longer clips or overlaps. (#33GitHub) - fix: a column mapped to both a positional aesthetic (
x/y) and a grouping aesthetic (fill/colour/group/…), e.g.,aes(x: "class", fill: "class"), now resolves the grouping aesthetic across aggregating stats (boxplot,summary,count/sum, histograms) instead of drawing every mark in the ink colour with an empty guide. (#31GitHub) - fix: continuous scales honour an explicit
breaksargument for axis ticks and continuous legend guides instead of ignoring it; breaks outside the domain are dropped. (#30GitHub) - fix:
geom-ribbon()draws one band per discretefill/colour/groupinstead of merging every group into a single ribbon. (#29GitHub) - fix:
plot(width: auto, height: auto)is allowed on an unbounded page, falling back to the default10cmby7cminstead of panicking. (#27GitHub) - fix:
compose()panels fill their cells instead of being letterboxed; their ownwidth/heightare discarded once the composition has a size, and the composition size falls back to16cmby12cmwhen the container is unbounded. (#26GitHub) - fix: legend labels wider than 2 cm no longer overlap the next swatch; each legend column reserves the label’s full width, most visible in horizontal legends. (#25GitHub)
- fix: the
composecollected legend placed ontoporbottomno longer clips its first swatch and is centred under the panels. (#19GitHub) - fix:
width/heightnow bound the whole image, including title, subtitle, caption, and plot-background padding; the data panel shrinks to fit and long titles wrap. (b53fab2GitHub) - docs: callout headers now sit on the type tint as a distinct band while the body uses the plain surface, and caution gets its own deeper mustard so it no longer matches warning. (#16GitHub)
- docs: tabset (panel-tabset) labels now follow the light/dark theme; the active tab label uses the brand primary colour in both schemes. (#15GitHub)
- docs: the development version is now downloadable from the dev documentation site and installable as a local package; release, Typst Universe, and development archives share an identical payload. (#14GitHub)
0.1
0.1.1 (2026-05-22)
- fix: centre collected
composeside legends against the panel grid. (994c9e8GitHub) - fix: apply plot background inset/outset even without a fill. (2f24982GitHub)
- docs: enable llms.txt output for the documentation site. (6b05d6aGitHub)
- docs: add a navbar version switcher between the stable and development docs. (95c3d9bGitHub)
0.1.0 (2026-05-20)
- feat: initial version of Gribouille.
Looking for a specific change? Browse the full commit history or the list of releases on GitHub.