Makie.jl
Makie.jl copied to clipboard
Can't construct legend from stacked barplot axis
Since a stacked barplot can't be constructed as a sequence of labeled plots, I'm not sure how to construct a legend other than from the axis. However, Legend(fig, stack_ax)
cannot find plots with labels, so fails.
using CairoMakie
tbl = (x = [1, 1, 1, 2, 2, 2, 3, 3, 3],
height = 0.1:0.1:0.9,
grp = [1, 2, 3, 1, 2, 3, 1, 2, 3],
grp1 = [1, 2, 2, 1, 1, 2, 1, 1, 2],
grp2 = [1, 1, 2, 1, 2, 1, 1, 2, 1]
)
fig = Figure()
fig[1,1] = ax = Axis(fig)
barplot!(ax, tbl.x, tbl.height,
stack = tbl.grp,
color = tbl.grp,
axis = (xticks = (1:3, ["left", "middle", "right"]),
title = "Stacked bars"),
)
fig[1,2] = Legend(fig, ax)
gives
ERROR: There are no plots with labels in the given axis that can be put in the legend. Supply labels to plotting functions like `plot(args...; label = "My label")`
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] layoutable(::Type{Legend}, fig_or_scene::Figure, axis::Axis, title::String; merge::Bool, unique::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables/legend.jl:539
[3] layoutable(::Type{Legend}, fig_or_scene::Figure, axis::Axis, title::String)
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables/legend.jl:538
[4] _layoutable(::Type{Legend}, ::Figure, ::Axis, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables.jl:69
[5] _layoutable(::Type{Legend}, ::Figure, ::Axis, ::Vararg{Any, N} where N)
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables.jl:69
[6] Legend(::Figure, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables.jl:49
[7] Legend(::Figure, ::Vararg{Any, N} where N)
@ Makie.MakieLayout ~/.julia/packages/Makie/xbI6d/src/makielayout/layoutables.jl:49
[8] top-level scope
@ REPL[21]:1
I think we need better support for extracting labels from plots... One hack was this: https://github.com/JuliaPlots/Makie.jl/blob/master/src/basic_recipes/series.jl#L122, but that doesn't work for stacked barplots... We should make it possible to overload the extraction of the labels for more complex scenarios
Is there a workaround to this issue? I have the same problem for grouped box-plots, and I can't figure out how to get a legend to work.
@bgroenks96 I ended up using AlgebraOfGraphics, which magically worked. plt = data(df) * frequency() * mapping(:x, color=:condition, stack=:condition => condition_sorter)
. YMMV
I feel like a good starting point would be making
barplot(1:3, [1,1,2]; group=[1,1,2], color=[1,1,2], label=["1". "1", "2"])
axislegend()
current_figure()
work, right now this throws an error
MethodError: no method matching initialize_block!(::Legend, ::Vector{AbstractPlot}, ::Vector{Vector{String}}, ::Nothing)
Closest candidates are:
initialize_block!(::Legend, ::Observable{Vector{Tuple{Union{Nothing, AbstractString}, Vector{LegendEntry}}}}) at ~/.julia/packages/Makie/fEZv2/src/makielayout/blocks/legend.jl:1
Stacktrace:
do we want to "internalize" this logic? https://github.com/JuliaPlots/Makie.jl/blob/ac6b5582fd5c17e3c57ae6d9cfc9a80138345701/docs/examples/plotting_functions/barplot.md?plain=1#L98-L103
so that we can directly pass labels = ...
?