How to make a series optional in AlgebraOfGraphics.jl

Abhro
Sat, 23 Aug 2025 22:57:17 +0000
Visualization

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)

3 posts - 2 participants