I have a “wide” DataFrame where one column is a shared vector of x-values, and two different columns are separate vectors of y-values. For example,
df = let
t = range(0, 9, length = 1000)
mass_lab_frame = @. cos(t)^2
mass_col_frame = @. sin(t)^2
(; t, mass_lab_frame, mass_col_frame)
end
And I want to plot the two mass series on the same graph, with an option to turn off the plot for mass_col_frame
. With Makie, it’s easily achieved
using CairoMakie
fig = Figure()
ax = Axis(fig[1,1], xlabel = "time", ylabel = "observed mass")
lines!(ax, df.t, df.mass_lab_frame, label = "Lab frame")
if should_plot_col_frame
lines!(ax, df.t, df.mass_col_frame, label = "Collider frame")
end
axislegend(ax)
fig
where should_plot_col_frame
is some boolean value set elsewhere.
How would I achieve the same effect in AlgebraOfGraphics? My current attempt is as follows:
using AlgebraOfGraphics
map_layer = mapping(
:t => "time",
[:mass_lab_frame, :mass_col_frame] .=> "observed mass",
color = dims(1) => renamer(["Lab frame", "Collider frame"])
)
spec = data(df) * map_layer * visual(Lines)
draw(spec)
This achieves (almost) the same effect as directly using Makie, but I’m not sure how to make the plot of :mass_col_frame
toggle-able within the framework of AoG.
I did consider making them separate layers, as
map_layer = mapping(:t => "time", :mass_lab_frame => "observed mass") +
mapping(:t => "time", :mass_col_frame => "observed mass") * should_plot_col_frame
and defining a type-pirated version of multiplication:
Base.:*(b::Bool, l::Layer) = b ? l : zerolayer()
Base.:*(l::Layer, b::Bool) = b * l # commutative
But that has both the series with the same color, and I cannot distinguish them with labels either. (For more details on this, also see How to label multiple histograms in AlgebraOfGraphics)