Makie.hist/hist! can't add a label for legend if bar_labels is specified

It seems like the legend doesn’t work for all situations.

This works:

use GLMakie
 h1=hist(rand(16,),bins = 10,  label="a", strokewidth = 1, strokecolor = :black, normalization = :probability)
axislegend()

And this works:

use GLMakie
h1=hist(rand(16,),bins = 10, strokewidth = 1, strokecolor = :black, normalization = :probability, bar_labels = :values, label_size=12,label_formatter=x-> round(x, digits=2))

But this fails and I think it should work:

use GLMakie
h1=hist(rand(16,),bins = 10, strokewidth = 1, strokecolor = :black, normalization = :probability, bar_labels = :values, label_size=12,label_formatter=x-> round(x, digits=2);label="A")
axislegend()

ERROR: No child plot elements found in plot of type MakieCore.Text{Tuple{Vector{Makie.GlyphCollection}}} but also no `legendelements` method defined.
Stacktrace:
  [1] error(s::String)
    @ Base .\error.jl:35
  [2] legendelements(plot::MakieCore.Text{Tuple{Vector{Makie.GlyphCollection}}}, legend::Legend)
    @ Makie C:\Users\use\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:427
  [3] (::Makie.var"#1705#1706"{Legend})(childplot::MakieCore.Text{Tuple{Vector{Makie.GlyphCollection}}})
    @ Makie .\none:0
  [4] iterate
    @ .\generator.jl:47 [inlined]
  [5] collect(itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}})
    @ Base .\array.jl:782
  [6] legendelements(plot::MakieCore.Text{Tuple{Vector{Point{3, Float32}}}}, legend::Legend)
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:429
  [7] (::Makie.var"#1705#1706"{Legend})(childplot::MakieCore.Text{Tuple{Vector{Point{3, Float32}}}})
    @ Makie .\none:0
  [8] iterate
    @ .\generator.jl:47 [inlined]
  [9] collect(itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}})
    @ Base .\array.jl:782
 [10] legendelements(plot::MakieCore.Text{Tuple{Vector{Tuple{String, Point{2, Float32}}}}}, legend::Legend)
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:429
 [11] (::Makie.var"#1705#1706"{Legend})(childplot::MakieCore.Text{Tuple{Vector{Tuple{String, Point{2, Float32}}}}})
    @ Makie .\none:0
 [12] iterate
    @ .\generator.jl:47 [inlined]
 [13] collect_to!(dest::Vector{Vector{LegendElement}}, itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}}, offs::Int64, st::Int64)
    @ Base .\array.jl:840
 [14] collect_to_with_first!(dest::Vector{Vector{LegendElement}}, v1::Vector{LegendElement}, itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}}, st::Int64)
    @ Base .\array.jl:818
 [15] collect(itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}})
    @ Base .\array.jl:792
 [16] legendelements(plot::Combined{Makie.barplot, Tuple{Vector{Point{2, Float32}}}}, legend::Legend)
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:429
 [17] (::Makie.var"#1705#1706"{Legend})(childplot::Combined{Makie.barplot, Tuple{Vector{Point{2, Float32}}}})
    @ Makie .\none:0
 [18] iterate
    @ .\generator.jl:47 [inlined]
 [19] collect(itr::Base.Generator{Vector{AbstractPlot}, Makie.var"#1705#1706"{Legend}})
    @ Base .\array.jl:782
 [20] legendelements(plot::Combined{Makie.hist, Tuple{Vector{Float64}}}, legend::Legend)
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:429
 [21] LegendEntry(label::String, contentelement::Combined{Makie.hist, Tuple{Vector{Float64}}}, legend::Legend; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:330
 [22] LegendEntry
    @ C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:324 [inlined]
 [23] (::Makie.var"#1708#1709"{Legend})(::Tuple{Combined{Makie.hist, Tuple{Vector{Float64}}}, String})
    @ Makie .\none:0
 [24] iterate
    @ .\generator.jl:47 [inlined]
 [25] collect(itr::Base.Generator{Base.Iterators.Zip{Tuple{Vector{AbstractPlot}, Vector{String}}}, Makie.var"#1708#1709"{Legend}})
    @ Base .\array.jl:782
 [26] Legend(fig_or_scene::Figure, contents::Vector{AbstractPlot}, labels::Vector{String}, title::Nothing; kwargs::Base.Pairs{Symbol, Any, NTuple{4, Symbol}, NamedTuple{(:bbox, :margin, :halign, :valign), Tuple{Observable{GeometryBasics.HyperRectangle{2, Int64}}, NTuple{4, Int64}, Symbol, Symbol}}})  
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:479
 [27] Legend(fig_or_scene::Figure, axis::Axis, title::Nothing; merge::Bool, unique::Bool, kwargs::Base.Pairs{Symbol, Any, NTuple{4, Symbol}, NamedTuple{(:bbox, :margin, :halign, :valign), Tuple{Observable{GeometryBasics.HyperRectangle{2, Int64}}, NTuple{4, Int64}, Symbol, Symbol}}})
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:534
 [28] Legend
    @ C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:531 [inlined]
 [29] #axislegend#1733
    @ C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:599 [inlined]
 [30] axislegend
    @ C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:598 [inlined]
 [31] #axislegend#1731
    @ C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:575 [inlined]
 [32] axislegend(ax::Axis)
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:575
 [33] axislegend()
    @ Makie C:\Users\user\.julia\packages\Makie\Ggejq\src\makielayout\blocks\legend.jl:575
 [34] top-level scope
    @ REPL[130]:1

Thoughts?

This looks llike a bug to me…

Ah yes the bug is that the legend elements fallback logic traverses all children and tries to find legend elements for them. In this case it finds some for the barplot part, but not for the text part. I think it could just be satisfied with finding any legend element as a fallback, it doesn’t have to find one for every child.

perhaps there needs to be a way to indicate which elements should be included in a legend and which shouldn’t. I don’t think anyone would want annotations to be in the legend…

There is, what legend elements are used for a given plot type is overloadable. The generic version just used to work for hist with the fallback to barplot until the text was added for the labels.

1 Like

Fix is up here Fix legendelements when children have no elements by jkrumbiegel · Pull Request #2982 · MakieOrg/Makie.jl · GitHub

1 Like