CeTZ Plot
Johannes Wolf
fenjalien
Version 0.1.0
1 Introduction ........................................................... 3
2 Usage ....................................................................... 3
3 Plot .......................................................................... 3
3.1.1 plot ................................................................. 3
3.1.2 add-anchor ................................................... 7
3.1.3 add .................................................................. 7
3.1.4 add-hline ..................................................... 10
3.1.5 add-vline ..................................................... 10
3.1.6 add-fill-between ........................................ 11
3.1.7 add-bar ........................................................ 12
3.1.8 add-boxwhisker ........................................ 14
3.1.9 add-contour ................................................ 15
3.1.10 add-errorbar ............................................. 16
3.1.11 annotate .................................................... 17
3.1.12 fraction ...................................................... 18
3.1.13 multiple-of ............................................... 19
3.1.14 sci ............................................................... 20
4 Chart ..................................................................... 20
4.1.1 barchart ....................................................... 20
4.1.2 boxwhisker ................................................. 21
4.1.3 columnchart ............................................... 22
4.1.4 piechart ....................................................... 24
CeTZ-Plot
1 Introduction
CeTZ-Plot is a simple ploing library for use with CeTZ.
2 Usage
is is the minimal starting point:
#import "@preview/cetz:0.2.2"
#import "@preview/cetz-plot:0.1.0"
#cetz.canvas({
import cetz.draw: *
import cetz-plot: *
...
})
Note that plot functions are imported inside the scope of the canvas block. All following example code
is expected to be inside a canvas block, with the plot module imported into the namespace.
3 Plot
3.1.1 plot
Create a plot environment. Data to be ploed is given by passing it to the plot.add or other ploing
functions. e plot environment supports different axis styles to draw, see its parameter axis-style:.
plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
plot.add(((0,0), (1,1), (2,.5), (4,3)))
})
To draw elements insides a plot, using the plots coordinate system, use the plot.annotate(..) func-
tion.
Parameters
plot(
body:
body
,
size: array ,
axis-style: none string ,
name: string ,
plot-style:
style
function
,
mark-style:
style
function
,
fill-below:
bool
,
legend: none auto coordinate ,
legend-anchor:
auto
string
,
legend-style:
style
,
..options:
any
)
body: body
Calls of plot.add or plot.add-* commands. Note that normal drawing commands like line or rect
are not allowed inside the plots body, instead wrap them in plot.annotate, which lets you select
the axes used for drawing.
size: array Default: (1, 1)
3/26
CeTZ-Plot
Plot size tuple of (<width>, <height>) in canvas units. is is the plots inner ploing size without
axes and labels.
axis-style: none or string Default: "scientific"
How the axes should be styled:
scientific Frames plot area using a rectangle and draw axes x (boom), y (le), x2 (top), and y2
(right) around it. If x2 or y2 are unset, they mirror their opposing axis.
scientific-auto Draw set (used) axes x (boom), y (le), x2 (top) and y2 (right) around the plot-
ting area, forming a rect if all axes are in use or a L-shape if only x and y are in use.
school-book Draw axes x (horizontal) and y (vertical) as arrows pointing to the right/top with
both crossing at  
le Draw axes x and y as arrows, while the y axis stays on the le (at x.min) and the x axis at
the boom (at y.min)
none Draw no axes (and no ticks).
none
"school-book"
"le"
"scientific"
let opts = (x-tick-step: none, y-tick-step: none, size: (2,1))
let data = cetz.plot.add(((-1,-1), (1,1),), mark: "o")
for name in (none, "school-book", "left", "scientific") {
plot.plot(axis-style: name, ..opts, data, name: "plot")
content(((0,-1), "-|", "plot.south"), repr(name))
set-origin((3.5,0))
}
name: string Default: none
e plots element name to be used when referring to anchors
plot-style: style or function Default: default-plot-style
Styling to use for drawing plot graphs. is style gets inherited by all plots and supports palette
functions. e following style keys are supported:
stroke: none or stroke Default: 1pt
Stroke style to use for stroking the graph.
fill: none or paint Default: none
Paint to use for filled graphs. Note that not all graphs may support filling and that you may have
to enable filling per graph, see plot.add(fill: ..).
mark-style: style or function Default: default-mark-style
Styling to use for drawing plot marks. is style gets inherited by all plots and supports palette
functions. e following style keys are supported:
stroke: none or stroke Default: 1pt
Stroke style to use for stroking the mark.
fill: none or paint Default: none
4/26
CeTZ-Plot
Paint to use for filling marks.
fill-below: bool Default: true
If true, the filled shape of plots is drawn below axes.
legend: none or auto or coordinate Default: auto
e position the legend will be drawn at. See plot-legends for information about legends. If set to
<auto>, the legend’s “default-placement” styling will be used. If set to a <coordinate>, it will be
taken as relative to the plot’s origin.
legend-anchor: auto or string Default: auto
Anchor of the legend group to use as its origin. If set to auto and lengend is one of the predefined
legend anchors, the opposite anchor to legend gets used.
legend-style: style Default: (:)
Style key-value overwrites for the legend style with style root legend.
..options: any
Axis options, see options below.
Options
You can use the following options to customize each axis of the plot. You must pass them as named
arguments prefixed by the axis name followed by a dash (-) they should target. Example: x-min: 0,
y-ticks: (..) or x2-label: [..].
label: none or content Default: "none"
e axis’ label. If and where the label is drawn depends on the axis-style.
min: auto or float Default: "auto"
Axis lower domain value. If this is set greater than than max, the axis’ direction is swapped
max: auto or float Default: "auto"
Axis upper domain value. If this is set to a lower value than min, the axis’ direction is swapped
equal: string Default: "none"
Set the axis domain to keep a fixed aspect ratio by multiplying the other axis domain by the plots
aspect ratio, depending on the other axis orientation (see horizontal). is can be useful to force
one axis to grow or shrink with another one. You can only “lock” two axes of different orientations.

plot.plot(size: (2,1), x-tick-step: 1, y-tick-step: 1,
x-equal: "y",
{
plot.add(domain: (0, 2 * calc.pi),
t => (calc.cos(t), calc.sin(t)))
})
horizontal: bool Default: "axis name dependant"
If true, the axis is considered an axis that gets drawn horizontally, vertically otherwise. e default
value depends on the axis name on axis creation. Axes which name start with x have this set to
true, all others have it set to false. Each plot has to use one horizontal and one vertical axis for
ploing, a combination of two y-axes will panic: (“y”, “y2”).
tick-step: none or auto or float Default: "auto"
5/26
CeTZ-Plot
e increment between tick marks on the axis. If set to auto, an increment is determined. When set
to none, incrementing tick marks are disabled.
minor-tick-step: none or float Default: "none"
Like tick-step, but for minor tick marks. In contrast to ticks, minor ticks do not have labels.
ticks: none or array Default: "none"
A List of custom tick marks to additionally draw along the axis. ey can be passed as an array of
<float> values or an array of (<float>, <content>) tuples for seing custom tick mark labels
per mark.
One
Two
plot.plot(x-tick-step: none, y-tick-step: none,
x-min: 0, x-max: 4,
x-ticks: (1, 2, 3),
y-min: 1, y-max: 2,
y-ticks: ((1, [One]), (2, [Two])),
{
plot.add(((0,0),))
})
Examples: (1, 2, 3) or ((1, [One]), (2, [Two]), (3, [Three]))
format: none or string or function Default: "float"
How to format the tick label: You can give a function that takes a <float> and return <content> to
use as the tick label. You can also give one of the predefined options:
float Floating point formaing rounded to two digits aer the point (see decimals)
sci Scientific formaing with 
󰍴
used as exponet syntax
 
let formatter(v) = if v != 0 {$ #{v/calc.pi} pi $} else {$ 0 $}
plot.plot(x-tick-step: calc.pi, y-tick-step: none,
x-min: 0, x-max: 2 * calc.pi,
x-format: formatter,
{
plot.add(((0,0),))
})
decimals: int Default: "2"
Number of decimals digits to display for tick labels, if the format is set to "float".
unit: none or content Default: "none"
Suffix to append to all tick labels.
mode: none or string Default: "none"
e scaling function of the axis. Takes lin (default) for linear scaling, and log for logarithmic scal-
ing.
base: none or number Default: "none"
e base to be used when labeling axis ticks in logarithmic scaling
grid: bool or string Default: "false"
If true or "major", show grid lines for all major ticks. If set to "minor", show grid lines for minor
ticks only. e value "both" enables grid lines for both, major- and minor ticks.
6/26
CeTZ-Plot
plot.plot(x-tick-step: 1, y-tick-step: 1,
y-minor-tick-step: .2,
x-min: 0, x-max: 2, x-grid: true,
y-min: 0, y-max: 2, y-grid: "both", {
plot.add(((0,0),))
})
break: bool Default: "false"
If true, add a “sawtooth” at the start or end of the axis line, depending on the axis bounds. If the axis
min. value is > 0, a sawtooth is added to the start of the axes, if the axis max. value is < 0, a sawtooth
is added to its end.
3.1.2 add-anchor
Add an anchor to a plot environment
is function is similar to draw.anchor but it takes an additional axis tuple to specify which axis co-
ordinate system to use.
Here
import cetz.plot
import cetz.draw: *
plot.plot(size: (2,2), name: "plot",
x-tick-step: none, y-tick-step: none, {
plot.add(((0,0), (1,1), (2,.5), (4,3)))
plot.add-anchor("pt", (1,1))
})
line("plot.pt", ((), "|-", (0,1.5)), mark: (start: ">"), name: "line")
content("line.end", [Here], anchor: "south", padding: .1)
Parameters
add-anchor(
name:
string
,
position: tuple ,
axes: tuple
)
name: string
Anchor name
position: tuple
Tuple of x and y values. Both values can have the special values “min” and “max”, which resolve to
the axis min/max value. Position is in axis space defined by the axes passed to axes.
axes: tuple Default: ("x", "y")
Name of the axes to use ("x", "y") as coordinate system for position. Note that both axes must
be used, as add-anchors does not create them on demand.
3.1.3 add
Add data to a plot environment.
Note: You can use this for scaer plots by seing the stroke style to none: add(..., style: (stroke:
none)).
7/26
CeTZ-Plot
Must be called from the body of a plot(..) command.
Parameters
add(
domain:
domain
,
hypograph: bool ,
epigraph: bool ,
fill: bool ,
fill-type:
string
,
style:
style
,
mark:
string
,
mark-size:
float
,
mark-style,
samples:
int
,
sample-at:
array
,
line:
string
dictionary
,
axes:
axes
,
label:
none
content
,
data:
array
function
)
domain: domain Default: auto
Domain of data, if data is a function. Has no effect if data is not a function.
hypograph: bool Default: false
Fill hypograph; uses the hypograph style key for drawing
epigraph: bool Default: false
Fill epigraph; uses the epigraph style key for drawing
fill: bool Default: false
Fill the shape of the plot
fill-type: string Default: "axis"
Fill type:
"axis" Fill the shape to y = 0
"shape" Fill the complete shape
style: style Default: (:)
Style to use, can be used with a palette function
mark: string Default: none
Mark symbol to place at each distinct value of the graph. Uses the mark style key of style for draw-
ing.
mark-size: float Default: .2
Mark size in cavas units
mark-style:
Default: (:)
samples: int Default: 50
Number of times the data function gets called for sampling y-values. Only used if data is of type
function. is parameter gets passed onto sample-fn.
sample-at: array Default: ()
8/26
CeTZ-Plot
Array of x-values the function gets sampled at in addition to the default sampling. is parameter
gets passed to sample-fn.
line: string or dictionary Default: "linear"
Line type to use. e following types are supported:
"linear" Draw linear lines between points
"spline" Calculate a Catmull-Rom through all points
"vh" Move vertical and then horizontal
"hv" Move horizontal and then vertical
"hvh" Add a vertical step in the middle
"raw" Like linear, but without linearization taking place. is is meant as a “fallback” for either
bad performance or bugs.
If the value is a dictionary, the type must be supplied via the type key. e following extra aributes
are supported:
"samples" <int> Samples of splines
"tension" <float> Tension of splines
"mid" <float> Mid-Point of hvh lines (0 to 1)
"epsilon" <float> Linearization slope epsilon for use with "linear", defaults to 0.
import cetz.plot
let points(offset: 0) = ((0,0), (1,1), (2,0), (3,1), (4,0)).map(((x,y)) => {
(x,y + offset * 1.5)
})
plot.plot(size: (12, 3), axis-style: none, {
plot.add(points(offset: 5), line: (type: "hvh", mid: .1))
plot.add(points(offset: 4), line: "hvh")
plot.add(points(offset: 3), line: "hv")
plot.add(points(offset: 2), line: "vh")
plot.add(points(offset: 1), line: "spline")
plot.add(points(offset: 0), line: "linear")
})
axes: axes Default: ("x", "y")
Name of the axes to use for ploing. Reversing the axes means rotating the plot by 90 degrees.
label: none or content Default: none
Legend label to show for this plot.
data: array or function
Array of 2D data points (numeric) or a function of the form x => y, where x is a value in domain
and y must be numeric or a 2D vector (for parametric functions).
9/26
CeTZ-Plot
import cetz.plot
plot.plot(size: (2, 2), axis-style: none, {
// Using an array of points:
plot.add(((0,0), (calc.pi/2,1),
(1.5*calc.pi,-1), (2*calc.pi,0)))
// Sampling a function:
plot.add(domain: (0, 2*calc.pi), calc.sin)
})
3.1.4 add-hline
Add horizontal lines at one or more y-values. Every lines start and end points are at their axis bounds.
cetz.plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
cetz.plot.add(domain: (0, 4*calc.pi), calc.sin)
// Add 3 horizontal lines
cetz.plot.add-hline(-.5, 0, .5)
})
Parameters
add-hline(
..y:
float
,
min: auto float ,
max: auto float ,
axes: array ,
style:
style
,
label:
none
content
)
..y: float
Y axis value(s) to add a line at
min: auto or float Default: auto
X axis minimum value or auto to take the axis minimum
max: auto or float Default: auto
X axis maximum value or auto to take the axis maximum
axes: array Default: ("x", "y")
Name of the axes to use for ploing
style: style Default: (:)
Style to use, can be used with a palee function
label: none or content Default: none
Legend label to show for this plot.
3.1.5 add-vline
Add vertical lines at one or more x-values. Every lines start and end points are at their axis bounds.
10/26
CeTZ-Plot
cetz.plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
cetz.plot.add(domain: (0, 2*calc.pi), calc.sin)
// Add 3 vertical lines
cetz.plot.add-vline(calc.pi/2, calc.pi, 3*calc.pi/2)
})
Parameters
add-vline(
..x:
float
,
min: auto float ,
max: auto float ,
axes: array ,
style:
style
,
label:
none
content
)
..x: float
X axis values to add a line at
min: auto or float Default: auto
Y axis minimum value or auto to take the axis minimum
max: auto or float Default: auto
Y axis maximum value or auto to take the axis maximum
axes: array Default: ("x", "y")
Name of the axes to use for ploing, note that not all plot styles are able to display a custom axis!
style: style Default: (:)
Style to use, can be used with a palee function
label: none or content Default: none
Legend label to show for this plot.
3.1.6 add-fill-between
Fill the area between two graphs. is behaves same as add but takes a pair of data instead of a single
data array/function. e area between both function plots gets filled. For a more detailed explanation
of the arguments, see add().
is can be used to display an error-band of a function.
cetz.plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
cetz.plot.add-fill-between(domain: (0, 2*calc.pi),
calc.sin, // First function/data
calc.cos) // Second function/data
})
11/26
CeTZ-Plot
Parameters
add-fill-between(
data-a:
array
function
,
data-b: array function ,
domain: domain ,
samples: int ,
sample-at:
array
,
line:
string
dictionary
,
axes:
array
,
label:
none
content
,
style:
style
)
data-a: array or function
Data of the first plot, see add().
data-b: array or function
Data of the second plot, see add().
domain: domain Default: auto
Domain of both data-a and data-b. e domain is used for sampling functions only and has no
effect on data arrays.
samples: int Default: 50
Number of times the data-a and data-b function gets called for sampling y-values. Only used if
data-a or data-b is of type function.
sample-at: array Default: ()
Array of x-values the function(s) get sampled at in addition to the default sampling.
line: string or dictionary Default: "linear"
Line type to use, see add().
axes: array Default: ("x", "y")
Name of the axes to use for ploing.
label: none or content Default: none
Legend label to show for this plot.
style: style Default: (:)
Style to use, can be used with a palee function.
3.1.7 add-bar
Add a bar- or column-chart to the plot
A bar- or column-chart is a chart where values are drawn as rectangular boxes.
12/26
CeTZ-Plot
Parameters
add-bar(
data:
array
,
x-key,
y-key,
error-key,
mode:
string
,
labels: none content array ,
bar-width:
float
,
bar-position:
string
,
cluster-gap:
float
,
whisker-size,
error-style,
style:
dictionary
,
axes:
axes
)
data: array
Array of data items. An item is an array containing a x an one or more y values. For example (0,
1) or (0, 10, 5, 30). Depending on the mode, the data items get drawn as either clustered or
stacked rects.
x-key: (int,string): Key to use for retreiving a bars x-value from a single data entry. is value gets
passed to the .at(...) function of a data item.
y-key: (auto,int,string,array): Key to use for retreiving a bars y-value. For clustered/stacked data,
this must be set to a list of keys (e.g. range(1, 4)). If set to auto, a but the first array-values of
a data item are used as y-values.
error-key: (none,int,string): Key to use for retreiving a bars y-error.
x-key:
Default: 0
y-key:
Default: auto
error-key:
Default: none
mode: string Default: "basic"
e mode on how to group data items into bars:
basic Add one bar per data value. If the data contains multiple values, group those bars next to
each other.
clustered Like “basic”, but take into account the maximum number of values of all items and
group each cluster of bars together having the width of the widest cluster.
stacked Stack bars of subsequent item values onto the previous bar, generating bars with the
height of the sume of all an items values.
stacked100 Like “stacked”, but scale each bar to height , making the different bars percent-
ages of the sum of an items values.
labels: none or content or array Default: none
A single legend label for “basic” bar-charts, or a a list of legend labels per bar category, if the mode
is one of “clustered”, “stacked” or “stacked100”.
bar-width: float Default: 1
Width of one data item on the y axis
bar-position: string Default: "center"
13/26
CeTZ-Plot
Positioning of data items relative to their x value.
“start”: e lower edge of the data item is on the x value (le aligned)
“center”: e data item is centered on the x value
“end”: e upper edge of the data item is on the x value (right aligned)
cluster-gap: float Default: 0
Spacing between bars insides a cluster.
whisker-size:
Default: .25
error-style:
Default: (:)
style: dictionary Default: (:)
Plot style
axes: axes Default: ("x", "y")
Plot axes. To draw a horizontal growing bar chart, you can swap the x and y axes.
3.1.8 add-boxwhisker
Add one or more box or whisker plots
cetz.plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
cetz.plot.add-boxwhisker((x: 1, // Location on x-axis
outliers: (7, 65, 69), // Optional outlier values
min: 15, max: 60, // Minimum and maximum
q1: 25, // Quartiles: Lower
q2: 35, // Median
q3: 50)) // Upper
})
Parameters
add-boxwhisker(
data:
array
dictionary
,
label: none content ,
axes: array ,
style: style ,
box-width:
float
,
whisker-width:
float
,
mark:
string
,
mark-size:
float
)
data: array or dictionary
dictionary or array of dictionaries containing the needed entries to plot box and whisker plot.
e following fields are supported:
x (number) X-axis value
min (number) Minimum value
max (number) Maximum value
q1, q2, q3 (number) artiles from lower to to upper
outliers (array of number) Optional outliers
label: none or content Default: none
Legend label to show for this plot.
14/26
CeTZ-Plot
axes: array Default: ("x", "y")
Name of the axes to use (“x”, “y”), note that not all plot styles are able to display a custom axis!
style: style Default: (:)
Style to use, can be used with a palee function
box-width: float Default: 0.75
Width from edge-to-edge of the box of the box and whisker in plot units. Defaults to 0.75
whisker-width: float Default: 0.5
Width from edge-to-edge of the whisker of the box and whisker in plot units. Defaults to 0.5
mark: string Default: "*"
Mark to use for ploing outliers. Set none to disable. Defaults to “x”
mark-size: float Default: 0.15
Size of marks for ploing outliers. Defaults to 0.15
3.1.9 add-contour
Add a contour plot of a sampled function or a matrix.
cetz.plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
cetz.plot.add-contour(x-domain: (-3, 3), y-domain: (-3, 3),
style: (fill: rgb(50,50,250,50)),
fill: true,
op: "<", // Find contours where data < z
z: (2.5, 2, 1), // Z values to find contours for
(x, y) => calc.sqrt(x * x + y * y))
})
Parameters
add-contour(
data:
array
function
,
label: none content ,
z: float array ,
x-domain: domain ,
y-domain:
domain
,
x-samples:
int
,
y-samples:
int
,
interpolate:
bool
,
op: auto string function ,
axes:
axes
,
style:
style
,
fill:
bool
,
limit:
int
)
data: array or function
A function of the signature (x, y) => z or an array of arrays of floats (a matrix) where the first
index is the row and the second index is the column.
label: none or content Default: none
Plot legend label to show. e legend preview for contour plots is a lile rectangle drawn with the
contours style.
z: float or array Default: (1,)
15/26
CeTZ-Plot
Z values to plot. Contours containing values above z (z >= 0) or below z (z < 0) get ploed. If you
specify multiple z values, they get ploed in the order of specification.
x-domain: domain Default: (0, 1)
X axis domain used if data is a function, that is the domain inside the function gets sampled.
y-domain: domain Default: (0, 1)
Y axis domain used if data is a function, see x-domain.
x-samples: int Default: 25
X axis domain samples (2 < n). Note that contour finding can be quite slow. Using a big sample count
can improve accuracy but can also lead to bad compilation performance.
y-samples: int Default: 25
Y axis domain samples (2 < n)
interpolate: bool Default: true
Use linear interpolation between sample values which can improve the resulting plot, especially if
the contours are curved.
op: auto or string or function Default: auto
Z value comparison oparator:
">", ">=", "<", "<=", "!=", "==" Use the operator for comparison of z to the values from
data.
auto Use “>=” for positive z values, “<=” for negative z values.
<function> Call comparison function of the format (plot-z, data-z) => boolean, where
plot-z is the z-value from the plots z argument and data-z is the z-value of the data get-
ting ploed. e function must return true if at the combinations of arguments a contour is
detected.
axes: axes Default: ("x", "y")
Name of the axes to use for ploing.
style: style Default: (:)
Style to use for ploing, can be used with a palee function. Note that all z-levels use the same style!
fill: bool Default: false
Fill each contour
limit: int Default: 50
Limit of contours to create per z value before the function panics
3.1.10 add-errorbar
Add x- and/or y-error bars
16/26
CeTZ-Plot
Parameters
add-errorbar(
pt:
tuple
,
x-error,
y-error,
label,
mark,
mark-size,
mark-style,
whisker-size:
float
,
style:
dictionary
,
axes:
axes
)
pt: tuple
Error-bar center coordinate tuple: (x, y)
x-error: (float,tuple): Single error or tuple of errors along the x-axis
y-error: (float,tuple): Single error or tuple of errors along the y-axis
mark: (none,string): Mark symbol to show at the error position (pt).
mark-size: (number): Size of the mark symbol.
mark-style: (style): Extra style to apply to the mark symbol.
x-error:
Default: 0
y-error:
Default: 0
label:
Default: none
mark:
Default: "o"
mark-size:
Default: .2
mark-style:
Default: (:)
whisker-size: float Default: .5
Width of the error bar whiskers in canvas units.
style: dictionary Default: (:)
Style for the error bars
label: (none,content): Label to tsh
axes: axes Default: ("x", "y")
Plot axes. To draw a horizontal growing bar chart, you can swap the x and y axes.
3.1.11 annotate
Add an annotation to the plot
An annotation is a sub-canvas that uses the plots coordinates specified by its x and y axis.
17/26
CeTZ-Plot
Here
import cetz.plot
plot.plot(size: (2,2), x-tick-step: none, y-tick-step: none, {
plot.add(domain: (0, 2*calc.pi), calc.sin)
plot.annotate({
rect((0, -1), (calc.pi, 1), fill: rgb(50,50,200,50))
content((calc.pi, 0), [Here])
})
})
Bounds calculation is done naively, therefore fixed size content can grow out of the plot. You can ad-
just the padding manually to adjust for that. e feature of solving the correct bounds for fixed size
elements might be added in the future.
Parameters
annotate(
body:
drawable
,
axes: axes ,
resize: bool ,
padding: none number dictionary ,
background:
bool
)
body: drawable
Elements to draw
axes: axes Default: ("x", "y")
X and Y axis names
resize: bool Default: true
If true, the plots axes get adjusted to contain the annotation
padding: none or number or dictionary Default: none
Annotation padding that is used for axis adjustment
background: bool Default: false
If true, the annotation is drawn behind all plots, in the background. If false, the annotation is drawn
above all plots.
3.1.12 fraction
Fraction tick formaer

󰆼
󰆺
󰈑
󰆺
󰈗
󰆺
󰇨
󰆺
󰇨
󰆺
󰈗
󰆺
󰈑
󰆺
󰆼
󰆺
plot.plot(size: (5,1),
x-format: plot.formats.fraction,
x-tick-step: 1/5,
y-tick-step: none, {
plot.add(calc.sin, domain: (-1, 1))
})
Parameters
fraction(
value: number ,
denom: auto int ,
eps: number
) -> Content if a matching fraction could be found or none
value: number
18/26
CeTZ-Plot
Value to format
denom: auto or int Default: auto
Denominator for result fractions. If set to auto, a hardcoded fraction table is used for finding frac-
tions with a denominator <= 11.
eps: number Default: 1e-6
Epsilon used for comparison
3.1.13 multiple-of
Multiple of tick formaer

󰈑
󰆼
󰇨
󰈗
󰇨
󰆼
󰇨
󰆼
󰇨
󰈗
󰈑
󰆼
󰆺
󰆼
󰈑
󰈗
plot.plot(size: (5,1),
x-format: plot.formats.multiple-of,
x-tick-step: calc.pi/4,
y-tick-step: none, {
plot.add(calc.sin, domain: (-calc.pi, 1.5 * calc.pi))
})
Parameters
multiple-of(
value:
number
,
factor: number ,
symbol: content ,
fraction: none true int ,
digits:
int
,
eps:
number
) ->
Content if a matching fraction could be found or none
value: number
Value to format
factor: number Default: calc.pi
Factor value is expected to be a multiple of.
symbol: content Default: $pi$
Suffix symbol. For value = 0, the symbol is not appended.
fraction: none or true or int Default: true
If not none, try finding matching fractions using the same mechanism as fraction. If set to an
integer, that integer is used as denominator. If set to none or false, or if no fraction could be found,
a real number with digits digits is used.
digits: int Default: 2
Number of digits to use for rounding
eps: number Default: 1e-6
Epsilon used for comparison
19/26
CeTZ-Plot
3.1.14 sci
Scientific notation tick formaer
 
󰈑
 
󰈑

󰈑

󰈑
plot.plot(size: (5,1),
x-format: plot.formats.sci,
x-tick-step: 1e3,
y-tick-step: none, {
plot.add(x => x, domain: (-2e3, 2e3))
})
Parameters
sci(
value:
number
,
digits: int
) -> Content
value: number
Value to format
digits: int Default: 2
Number of digits for rouding the factor
4 Chart
4.1.1 barchart
Draw a bar chart. A bar chart is a chart that represents data with rectangular bars that grow from le
to right, proportional to the values they represent.
Styling
Root: barchart.
bar-width: float Default: 0.8
Width of a single bar (basic) or a cluster of bars (clustered) in the plot.
y-inset: float Default: 1
Distance of the plot data to the plot’s edges on the y-axis of the plot.
You can use any plot or axes related style keys, too.
e barchart function is a wrapper of the plot API. Arguments passed to ..plot-args are passed to
the plot.plot function.
Parameters
barchart(
data:
array
,
label-key: int string ,
value-key: int string ,
error-key: none int string ,
mode:
string
,
size:
array
,
bar-style:
style
function
,
x-label:
content
none
,
x-unit:
content
auto
,
y-label:
content
none
,
labels:
none
content
,
..plot-args:
any
)
20/26
CeTZ-Plot
data: array
Array of data rows. A row can be of type array or dictionary, with label-key and value-key being
the keys to access a rows label and value(s).
Example
(([A], 1), ([B], 2), ([C], 3),)
label-key: int or string Default: 0
Key to access the label of a data row. is key is used as argument to the rows .at(..) function.
value-key: int or string Default: 1
Key(s) to access values of a data row. ese keys are used as argument to the rows .at(..) function.
error-key: none or int or string Default: none
Key(s) to access error values of a data row. ese keys are used as argument to the rows .at(..)
function.
mode: string Default: "basic"
Chart mode:
basic Single bar per data row
clustered Group of bars per data row
stacked Stacked bars per data row
stacked100 Stacked bars per data row relative to the sum of the row
size: array Default: (auto, 1)
Chart size as width and height tuple in canvas unist; width can be set to auto.
bar-style: style or function Default: palette.red
Style or function (idx => style) to use for each bar, accepts a palee function.
x-label: content or none Default: none
x axis label
x-unit: content or auto Default: auto
Tick suffix added to each tick label
y-label: content or none Default: none
Y axis label
labels: none or content Default: none
Legend labels per x value group
..plot-args: any
Arguments to pass to plot.plot
4.1.2 boxwhisker
Add one or more box or whisker plots.



cetz.chart.boxwhisker(size: (2,2), label-key: none,
y-min: 0, y-max: 70, y-tick-step: 20,
(x: 1, min: 15, max: 60,
q1: 25, q2: 35, q3: 50))
21/26
CeTZ-Plot
Styling
Root boxwhisker
box-width: float Default: 0.75
e width of the box. Since boxes are placed 1 unit next to each other, a width of would make
neighbouring boxes touch.
whisker-width: float Default: 0.5
e width of the whisker, that is the horizontal bar on the top and boom of the box.
mark-size: float Default: 0.15
e scaling of the mark for the boxes outlier values in canvas units.
You can use any plot or axes related style keys, too.
Parameters
boxwhisker(
data:
array
dictionary
,
size,
label-key: integer string ,
mark: string ,
..plot-args:
any
)
data: array or dictionary
Dictionary or array of dictionaries containing the needed entries to plot box and whisker plot.
See plot.add-boxwhisker for more details.
Examples:
(x: 1 // Location on x-axis
outliers: (7, 65, 69), // Optional outliers
min: 15, max: 60 // Minimum and maximum
q1: 25, // Quartiles: Lower
q2: 35, // Median
q3: 50) // Upper
size (array) : Size of chart. If the second entry is auto, it automatically scales to accommodate the
number of entries ploed
size:
Default: (1, auto)
label-key: integer or string Default: 0
Index in the array where labels of each entry is stored
mark: string Default: "*"
Mark to use for ploing outliers. Set none to disable. Defaults to “x”
..plot-args: any
Additional arguments are passed to plot.plot
4.1.3 columnchart
Draw a column chart. A column chart is a chart that represents data with rectangular bars that grow
from boom to top, proportional to the values they represent.
22/26
CeTZ-Plot
Styling
Root: columnchart.
bar-width: float Default: 0.8
Width of a single bar (basic) or a cluster of bars (clustered) in the plot.
x-inset: float Default: 1
Distance of the plot data to the plot’s edges on the x-axis of the plot.
You can use any plot or axes related style keys, too.
e columnchart function is a wrapper of the plot API. Arguments passed to ..plot-args are passed
to the plot.plot function.
Parameters
columnchart(
data:
array
,
label-key: int string ,
value-key: int string ,
error-key: none int string ,
mode:
string
,
size:
array
,
bar-style:
style
function
,
x-label:
content
none
,
y-unit:
content
auto
,
y-label:
content
none
,
labels:
none
content
,
..plot-args:
any
)
data: array
Array of data rows. A row can be of type array or dictionary, with label-key and value-key being
the keys to access a rows label and value(s).
Example
(([A], 1), ([B], 2), ([C], 3),)
label-key: int or string Default: 0
Key to access the label of a data row. is key is used as argument to the rows .at(..) function.
value-key: int or string Default: 1
Key(s) to access value(s) of data row. ese keys are used as argument to the rows .at(..) function.
error-key: none or int or string Default: none
Key(s) to access error values of a data row. ese keys are used as argument to the rows .at(..)
function.
mode: string Default: "basic"
Chart mode:
basic Single bar per data row
clustered Group of bars per data row
stacked Stacked bars per data row
stacked100 Stacked bars per data row relative to the sum of the row
size: array Default: (auto, 1)
23/26
CeTZ-Plot
Chart size as width and height tuple in canvas unist; width can be set to auto.
bar-style: style or function Default: palette.red
Style or function (idx => style) to use for each bar, accepts a palee function.
x-label: content or none Default: none
x axis label
y-unit: content or auto Default: auto
Tick suffix added to each tick label
y-label: content or none Default: none
Y axis label
labels: none or content Default: none
Legend labels per y value group
..plot-args: any
Arguments to pass to plot.plot
4.1.4 piechart
Draw a pie- or donut-chart
6%
12%
8%
12%
8%
11%
10%
8%
14%
11%
import cetz.chart
let data = (24, 31, 18, 21, 23, 18, 27, 17, 26, 13)
let colors = gradient.linear(red, blue, green, yellow)
chart.piechart(
data,
radius: 1.5,
slice-style: colors,
inner-radius: .5,
outer-label: (content: "%",))
Styling
Root piechart
radius: number Default: 1
Outer radius of the chart.
inner-radius: number Default: 0
Inner radius of the chart slices. If greater than zero, the chart becomes a “donut-chart”.
gap: number or angle Default: 0.5deg
Gap between chart slices to leave empty. is does not increase the charts radius by pushing slices
outwards, but instead shrinks the slice. Big values can result in slices becoming invisible if no space
is le.
outset-offset: number or ratio Default: 10%
Absolute, or radius relative distance to push slices marked for “outseing” outwards from the center
of the chart.
outset-offset: string Default: "OFFSET"
e mode of how to perform “outseing” of slices:
24/26
CeTZ-Plot
“OFFSET”: Offset slice position by outset-offset, increasing their gap to their siblings
“RADIUS”: Offset slice radius by outset-offset, which scales the slice and leaves the gap un-
changed
start: angle Default: 90deg
e pie-charts start angle (ccw). You can use this to draw charts not forming a full circle.
stop: angle Default: 450deg
e pie-charts stop angle (ccw).
clockwise: bool Default: true
e pie-charts rotation direction.
outer-label.content: none or string or function Default: "LABEL"
Content to display outsides the charts slices. ere are the following predefined values:
LABEL Display the slices label (see label-key)
% Display the percentage of the items value in relation to the sum of all values, rounded to the
next integer
VALUE Display the slices value
If passed a <function> of the format (value, label) => content, that function gets called with
each slices value and label and must return content, that gets displayed.
outer-label.radius: number or ratio Default: 125%
Absolute, or radius relative distance from the charts center to position outer labels at.
outer-label.angle: angle or auto Default: 0deg
e angle of the outer label. If passed auto, the label gets rotated, so that the baseline is parallel to
the slices secant.
outer-label.anchor: string Default: "center"
e anchor of the outer label to use for positioning.
inner-label.content: none or string or function Default: none
Content to display insides the charts slices. See outer-label.content for the possible values.
inner-label.radius: number or ratio Default: 150%
Distance of the inner label to the charts center. If passed a <ratio>, that ratio is relative to the mid
between the inner and outer radius (inner-radius and radius) of the chart
inner-label.angle: angle or auto Default: 0deg
See outer-label.angle.
inner-label.anchor: string Default: "center"
See outer-label.anchor.
legend.label: none or string or function Default: "LABEL"
See outer-label.content. e legend gets shown if this key is set != none.
Anchors
e chart places one anchor per item at the radius of it’s slice that gets named "item-<index>" (outer
radius) and "item-<index>-inner" (inner radius), where index is the index of the sclice data in data.
25/26
CeTZ-Plot
Parameters
piechart(
data:
array
,
value-key: none int string ,
label-key: none int string ,
outset-key: none int string ,
outset: none int array ,
slice-style: function array gradient ,
name,
..style
)
data: array
Array of data items. A data item can be:
A number: A number that is used as the fraction of the slice
An array: An array which is read depending on value-key, label-key and outset-key
A dictionary: A dictionary which is read depending on value-key, label-key and outset-key
value-key: none or int or string Default: none
Key of the “value” of a data item. If for example data items are passed as dictionaries, the value-key
is the key of the dictionary to access the items chart value.
label-key: none or int or string Default: none
Same as the value-key but for geing an items label content.
outset-key: none or int or string Default: none
Same as the value-key but for geing if an item should get outset (highlighted). e outset can be a
bool, float or ratio. If of type bool, the outset distance from the style gets used.
outset: none or int or array Default: none
A single or multiple indices of items that should get offset from the center to the outsides of the
chart. Only used if outset-key is none!
slice-style: function or array or gradient Default: palette.red
Slice style of the following types:
function: A function of the form index => style that must return a style dictionary. is can be
a palette function.
array: An array of style dictionaries or fill colors of at least one item. For each slice the style at
the slices index modulo the arrays length gets used.
gradient: A gradient that gets sampled for each data item using the the slices index divided by the
number of slices as position on the gradient.
If one of stroke or fill is not in the style dictionary, it is taken from the charts style.
name:
Default: none
..style:
26/26