Makie: how to remove a legend from an axis

Hi, I’m making a dashboard and I’m using a lot of mutating functions to make an interactive plot that changes its content based on a menu selection. When I change the plot, I remove the former one from the axis using empty!(ax). The problem is that the legend is not linked to the axis but to the GridPosition of the axis. But I can’t find it in the fields of the GridPosition object.
Here’s a MWE

using GLMakie
p = lines(rand(10), label = "foo")
function add_a_legend!(p) = axislegend(p.axis); return nothing end
add_a_legend!(p)
empty!(p.axis)

The legend is still there. But because I don’t have the legend variable in scope, I can’t use delete! directly. And I also can’t find it when I dig the p.figure[1,1] object.

I can change the function so that it returns the legend but I find this really cumbersome/impractical to have to return the Legend all the way up the callstack, and thus change all the functions. Is there a way to do this that I am not aware of ?

It would be nice if something like empty!(p.figure[1,1, Inner()]) worked.

2 Likes

p.figure.content should have it

Thank you

Although,
if I have two axes in the figure, each with a legend, how do I know which legend is on the axis I am emptying ?

using GLMakie
f = Figure()
ax1 = f[1,1] = Axis(f)
ax2 = f[1,2] = Axis(f)
p1 = lines!(ax1, rand(10), label = "foo")
p2 = lines!(ax2, rand(10), label = "bar")
function add_a_legend!(ax) axislegend(ax); return nothing end
add_a_legend!(ax1)
add_a_legend!(ax2)
empty!(ax1)
[delete!(leg) for leg in f.content if leg isa Legend]

will remove the Legend from both axis, how do I identify which is where in the figure ?

1 Like

I don’t think there’s an easy way to check that currently. The link to the axis exists only through the ax.scene.px_area observable. You could theoretically check which axis has the scene whose px_area observable is referenced in the legend’s suggestedbbox observable

I though I had found a workaround using SubLayouts:

using GLMakie
f = Figure()
gl1 = f[1,1] = GridLayout()
gl2 = f[1,2] = GridLayout()
ax1 = gl1[1,1] = Axis(f)
ax2 = gl2[1,1] = Axis(f)
p1 = lines!(ax1, rand(10), label = "foo")
p2 = lines!(ax2, rand(10), label = "bar")
function add_a_legend!(ax) axislegend(ax); return nothing end
add_a_legend!(ax1)
add_a_legend!(ax2)
empty!(ax1)
for leg in contents(gl1) 
    if  leg isa Legend
        delete!(leg)
    end
end

but contents only contains the Axis, not the legend. And I found that this is because I use axislegend(). Doing it directly with the Legend constructor works:

f = Figure()
gl1 = f[1,1] = GridLayout()
gl2 = f[1,2] = GridLayout()
ax1 = gl1[1,1] = Axis(f)
ax2 = gl2[1,1] = Axis(f)
p1 = lines!(ax1, rand(10), label = "foo")
p2 = lines!(ax2, rand(10), label = "bar")
Legend(gl1[1,1], [p1], ["foo"], tellwidth = false, tellhight = false)
contents(gl1) # contains the legend
for leg in contents(gl1) 
    if  leg isa Legend
        delete!(leg)
    end
end # correctly deletes the left legend

Do you want me to open an issue on this ?

Sure go ahead, I’m not sure in what other way I should link legend and axis, because legends in makie don’t have a tight one to one correspondence with Axes

I know this is 2-year-old post, but I found an easier way is simply to store the Legend object for deletion later:

f=Figure()
ax  = Axis(f[1,1])
lines!(ax, rand(10),label="foo")
leg = axislegend()
# do other stuff here
delete!(leg)         # does what you want
empty!(ax)         # clears the lines

Hope this helps (I am new to GLMakie…)

3 Likes