[AlgebraOfGraphics.jl] place legend inside figure

Is it possible to place legends inside figures with AlgebraOfGraphics.jl? I am looking for a functionality similar to what Makie.jl's axislegend function provides.

1 Like

Hello @TheLateKronos, have you found a solution to this problem?

Nope.

begin
	using CairoMakie, AlgebraOfGraphics
	
	df = (
	    x=rand(500),
	    y=rand(500),
	    k=rand(["a", "b", "c"], 500),
	    l=rand(["d", "e", "f"], 500),
	)
	plt = data(df) * mapping(:x, :y, color=:k, marker=:l) * visual(Scatter)

	# use `draw!` to draw into an existing figure
	fig = Figure()
	ag = draw!(fig[1,1], plt)
	
	# use internal function to compute legend components
	leg = AlgebraOfGraphics.compute_legend(ag)

	# add standard legend
	Legend(fig[1,2], leg...)

	# add axis legend
	ax = fig[1,1] |> contents |> first |> contents |> first # get the axis
	axislegend(ax, leg...)

	fig
end

image

5 Likes

Thank you very much @fabgrei and all this community!

1 Like

I could be misunderstanding the use case here, but would just using legend! work as well?

using CairoMakie, AlgebraOfGraphics

df = (
    x=rand(500),
    y=rand(500),
    k=rand(["a", "b", "c"], 500),
    l=rand(["d", "e", "f"], 500),
)

plt = data(df) * mapping(:x, :y, color=:k, marker=:l) * visual(Scatter)

fig = Figure()
gridpos = fig[1, 1]

f = draw!(gridpos, plt)
legend!(gridpos, f; tellwidth=false, halign=:right, valign=:top, margin=(10, 10, 10, 10))

fig

3 Likes

And you can set a padding on the legend as well (or margin, I think that one’s the outside)

Thanks, took a peek at axislegend to see what values were being used and added it to the example

btw, would it make sense to add a position keyword for Legend to have it more closely match axislegend? Using position=:rt instead of halign=:right, valign=:top is really nice

1 Like

I’m starting to doubt that position was a good idea, I thought it was a nice shortcut at the time and was inspired by other packages, but the align thing is much simpler. Although it would be an option to go through the motions and refactor GridLayoutBase so it uses only one align instead of halign and valign, and then one could do align = :cc or so as a shortcut. Would be pretty breaking though.

Oh, I thought position just passed the corresponding halign/valign to Legend via legend_position_to_aligns? Do you mean that this is probably more trouble than it’s worth for supporting other types of positioning, like in this issue here for example? `axislegend` cannot be positioned using a Tuple of numbers · Issue #2006 · JuliaPlots/Makie.jl · GitHub