Customizing legend

Hello,
I am trying to graph a scatter of my observations with a line of my predictions.
Here is the code:

plotted2_Emax = @chain df_est2_Emax begin
    data(_) *
    mapping(:time => "Time(minutes)",
        :dv_fdiss => "Percent dissolved",
        color = :dtd50 => nonnumeric => "TD50") *
    visual(Scatter, markersize = 12) +
    data(_) * 
    mapping(:time => "Time(minutes)",
        :dv_fdiss_pred => "Percent dissolved",
        line = :dtd50 => nonnumeric => "TD50") *
    visual(Lines, linewidth = 4, color = :gray0)
    draw(axis = (;xticks = 0:15:120, yticks = 0:10:100), legend = (;framevisible=false))
end

And here is the generated figure:
image

I want the symbols in the legend to just be circles (no line) as I thought this is what it would be for “Scatter” visualization. Is there also a way I can group the colored symbols under the word “Observations” and put a single black line under the word “Predicted”? From online I can only see how to customize the legend that is automatically generated, but is there a way to manipulate what is shown in the legend or is it always just automatically generated?

I want the symbols in the legend to just be circles (no line) as I thought this is what it would be for “Scatter” visualization.

Remember you are adding two layers via + , so, as the grouping variable is the same, it automatically infers the overlap. You can suppress the line in the scatter point in the legend by simply doing draw(legend=(; framevisible=false, linewidth=0.0))

Yes. color = :dtd50 => nonnumeric => "TD50" change this to color = :dtd50 => nonnumeric => "Observations"

and put a single black line under the word “Predicted”?

checking

I’m not sure if AlgebraOfGraphics can concatenate a legend together like that, where the different layers are listed in sequence.

But a lot of manual things are possible with legends, see the docs: Legend

It’s also possible to add things to an existing legend, however what I’m showing here is not public API and could change at any time. A public API to do similar things is still needed. The idea is to access the structure of the legend that holds all the information about legend entries, add an entry to it and update the changed Observable via notify. This is just to show that AlgebraOfGraphics/Makie plots are still malleable after creating them, even if one has to poke around in the internals a little:

using AlgebraOfGraphics
using CairoMakie
using DataFrames
using Chain


df = @chain begin
    DataFrame(group = 1:5)
    groupby(:group)
    combine(:group => (g -> (x = 1:100, y = (1:100) .+ 20g)) => AsTable)
    transform(:y => (y -> y .+ 5 .* randn.()) => :ymeas)
end


fgrid = data(df) *
    (
        mapping(:x, :ymeas, color = :group => nonnumeric) +
        mapping(:x, :y, group = :group => nonnumeric) * visual(Lines)
    ) |> draw

legend = fgrid.figure.content[2]
entrygroups = legend.entrygroups
first_group = entrygroups[][1]
first_group_entries = first_group[2]

push!(
    first_group_entries,
    LegendEntry("predicted", [LineElement()], legend)
)
notify(entrygroups)

fgrid

2 Likes

Wow that is exactly what I was looking for. Thank you!