cetz-plot
cetz-plot copied to clipboard
Mixing charts and plots
Hello,
I stumbled upon this package today looking for something to draw small charts in a Document of mine. In particular I'd like to draw a barchart (or columchart as you call it) but with an added hline for clarity.
I've read the docs (though not entirely) and I might be missing something trivial, but currently I'm at a loss at how to mix plot and chart elements.
According to the docs:
The barchart function is a wrapper of the plot API. Arguments passed to ..plot-args are passed to the plot.plot function.
and I've had a look at the source code as well and it appears there is no mechanism to "inject" other elements into the plot.plot call. In the docs I see that plot has a body argument which reads as if it allows injecting other drawable objects, but using it (see my example below) doesn't turn up anything.
Am I doing something wrong, or is this currently not supported?
I guess I could always copy out the columnchart function into my own document and use/adapt it from there, but I'd prefer not to duplicate your code.
Here's a MWE:
#import "@preview/cetz:0.3.2"
#import "@preview/cetz-plot:0.1.1"
#let plot_data = (
([A], 100),
([B], 85),
([C], 61),
([D], 30),
([E], 20),
)
#cetz.canvas({
import cetz: draw
import cetz-plot: chart, plot
draw.set-style(legend: (fill: white), barchart: (bar-width: .8, cluster-gap: .0))
chart.columnchart(
mode: "basic",
size: (15, 5),
label-key: 0,
value-key: 1,
y-label: [reduction of something],
x-label: [cumulated stuff],
y-format: x => [#x],
y-tick-step: 10,
plot_data,
// Doesn't work...
//plot-args: plot.add-hline(60),
// Doesn't work either...
//plot-args: (
// body: plot.add-hline(60)
//),
)
// Doesn't work...
//plot.add-hline(60),
})
Hi, this is indeed suboptimal. The chart API is a wrapper of plot.plot that does some things for you, but currently, you cannot really mix them. I will create a ticket to allow passing further plot commands to charts!
Here is a starting point for doing your chart with the plot API:
#import "@preview/cetz:0.3.2"
#import "@preview/cetz-plot:0.1.1"
#let plot-data = (
([A], 100),
([B], 85),
([C], 61),
([D], 30),
([E], 20),
)
#cetz.canvas({
import cetz: draw
import cetz-plot: chart, plot
draw.set-style(legend: (fill: white), barchart: (bar-width: .8, cluster-gap: .0))
let plot-data = plot-data.enumerate().map(((i, item)) => {
// x, y, label
(i, item.at(1), item.at(0))
})
plot.plot(
mode: "basic",
size: (15, 5),
label-key: 0,
value-key: 1,
y-label: [reduction of something],
x-label: [cumulated stuff],
y-format: x => [#x],
y-tick-step: 10,
x-tick-step: none,
x-ticks: plot-data.map(((x, _, label)) => (x, label)),
x-min: -.5,
x-max: plot-data.len() - .5,
{
plot.add-bar(plot-data, x-key: 0, y-key: 1, bar-width: .8)
plot.add-hline(60)
}
)
})
Link #108
Thanks for clarifying!
In that case I'll give copying and manually modifying your code a stab for now.