VegaLite.jl
VegaLite.jl copied to clipboard
Document rules for vega-lite layer composition
While there are examples in the documentation that use various forms of layer composition, I am often very unclear on how to translate vega-lite examples into syntax VegaLite.jl translates correctly to the same underlying format.
For example, I am trying to add a dotted line at 50% to indicate chance-level performance to a graph with points and error bars. An example of how to add such a horizontal line in vega-lite is here.
This example requires nesting layers with data included separately for the layers: one layer with the elements of the bars (or, in the use case I hope to translate the example to, the point and error bar), the other layer with the horizontal line annotation (which uses a single data point as its data set). It isn't clear to me if this nesting is possible and/or how it would translate to usage with the @vlplot
macro.
I did eventually figure this out:
here's my spec
pl =
@vlplot() +
@vlplot(data=[{}], mark=:rule,
encoding = {
y = {datum = 50, type=:quantitative},
strokeDash = {value = [2,2]}
}) +
(best_vals |>
@vlplot(x={:winlen, type=:ordinal, axis={title="Length (s)"}}) +
@vlplot(mark={:errorbar,filled=true},
y={:low,scale={zero=true}, axis={title=""},type=:quantitative},
y2={:high, type=:quantitative}, color={:salience, type=:nominal}) +
@vlplot(mark={:point,filled=true},
y={:correct,type=:quantitative,scale={zero=true},axis={title="% Correct Classification"}},
color={:salience, type=:nominal}))
I think I understand the logic, so I am happy to improve the documentation on this front at some point (I am little overwhelmed with childcare duties due to COVID-19, so can't help right now). I think the rules are: you add layers to a master @vlplot call. In this sense the meaning of +
for the first call is different. To nest layers, you need to have a separate "master" @vlplot command to call +
on.
Here's the data in best_vals
│ Row │ winlen │ salience │ correct │ low │ high │
│ │ Float64 │ Categorical… │ Float64 │ Float64 │ Float64 │
├─────┼─────────┼──────────────┼─────────┼─────────┼─────────┤
│ 1 │ 0.17 │ :high │ 85.1064 │ 80.8511 │ 89.3617 │
│ 2 │ 0.17 │ :low │ 80.0 │ 73.3333 │ 86.6667 │
│ 3 │ 1.08 │ :high │ 80.0 │ 73.3333 │ 86.6667 │
│ 4 │ 1.08 │ :low │ 97.5 │ 95.0 │ 100.0 │
So the reason that I still haven't written the composition doc chapter is that I don't like what we have right now... My current thinking on how to clean this up is in https://github.com/queryverse/VegaLite.jl/issues/230, feedback would be most welcome!
Your understanding of the layering is correct. I think the only small point I'd have is that I think you could pipe the data into the top level spec (i.e. have it flow into every layer), and then for the layer with the line you just use datum
, and I think that will then ignore the data that you piped into the spec. Caveat: I'm not sure and haven't tried. But I think this would work:
pl =
best_vals |>
@vlplot() +
@vlplot(:rule, y={datum=50, type=:quantitative}, strokeDash={value=[2,2]}) +
@vlplot(x={"winlen:o", axis={title="Length (s)"}}) +
@vlplot(mark={:errorbar,filled=true},
y={"low:q", scale={zero=true}, axis={title=""}},
y2={:high, type=:quantitative}, color={:salience, type=:nominal}) +
@vlplot(mark={:point,filled=true},
y={:correct,type=:quantitative,scale={zero=true},axis={title="% Correct Classification"}},
color={:salience, type=:nominal})
Ah, got it, I see: hope some of my feedback there is helpful. I will try out the piping at the top to see if it works and report back here.