From 5028ecdc98392a38b837515e54aaa0cd8ab9ab13 Mon Sep 17 00:00:00 2001 From: Julius Krumbiegel <22495855+jkrumbiegel@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:41:33 +0200 Subject: [PATCH] Allow hiding legend or colorbar via `show = false` (#547) Fixes #428 --- CHANGELOG.md | 1 + src/draw.jl | 19 ++++++++++++++----- src/guides/legend.jl | 11 +++++++++-- test/legend.jl | 30 ++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 414711068..80fb988ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Added `bar_labels` to `BarPlot`'s aesthetic mapping [#544](https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/544). +- Added ability to hide legend or colorbar by passing, e.g., `legend = (; show = false)` to `draw` [#547](https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/547). ## v0.8.5 - 2024-08-27 diff --git a/src/draw.jl b/src/draw.jl index 9413210d3..08b1b95b8 100644 --- a/src/draw.jl +++ b/src/draw.jl @@ -41,7 +41,10 @@ In practice, `d` will often be a [`AlgebraOfGraphics.Layer`](@ref) or [`AlgebraOfGraphics.Layers`](@ref). Scale options can be passed as an optional second argument. The output can be customized by passing named tuples or dictionaries with settings via the `axis`, `figure`, `facet`, `legend` or `colorbar` keywords. -Legend and colorbar are drawn automatically. For finer control, use [`draw!`](@ref), +Legend and colorbar are drawn automatically unless `show = false` is passed to the keyword +arguments of either `legend` or `colorbar`. + +For finer control, use [`draw!`](@ref), [`legend!`](@ref), and [`colorbar!`](@ref) independently. """ function draw(d::AbstractDrawable, scales::Scales = scales(); @@ -57,6 +60,8 @@ function draw(d::AbstractDrawable, scales::Scales = scales(); return _draw(d, scales; axis, figure, facet, legend, colorbar) end +_remove_show_kw(pairs) = filter(((key, value),) -> key !== :show, pairs) + function _draw(d::AbstractDrawable, scales::Scales; axis, figure, facet, legend, colorbar) @@ -64,8 +69,12 @@ function _draw(d::AbstractDrawable, scales::Scales; grid = plot!(f, d, scales; axis) fg = FigureGrid(f, grid) facet!(fg; facet) - colorbar!(fg; pairs(colorbar)...) - legend!(fg; pairs(legend)...) + if get(colorbar, :show, true) + colorbar!(fg; _remove_show_kw(pairs(colorbar))...) + end + if get(legend, :show, true) + legend!(fg; _remove_show_kw(pairs(legend))...) + end resize_to_layout!(fg) return fg end @@ -77,13 +86,13 @@ function draw(scales::Scales = scales(); kwargs...) end """ - draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet, legend, colorbar]) + draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet]) Draw a [`AlgebraOfGraphics.AbstractDrawable`](@ref) object `d` on `fig`. In practice, `d` will often be a [`AlgebraOfGraphics.Layer`](@ref) or [`AlgebraOfGraphics.Layers`](@ref). `fig` can be a figure, a position in a layout, or an axis if `d` has no facet specification. -The output can be customized by passing named tuples or dictionaries with settings via the `axis`, `facet`, `legend` or `colorbar` keywords. +The output can be customized by passing named tuples or dictionaries with settings via the `axis` or `facet` keywords. """ function draw!(fig, d::AbstractDrawable, scales::Scales = scales(); axis=NamedTuple(), facet=NamedTuple(), palette=nothing) diff --git a/src/guides/legend.jl b/src/guides/legend.jl index 7f35e5f02..f30854192 100644 --- a/src/guides/legend.jl +++ b/src/guides/legend.jl @@ -6,10 +6,17 @@ function legend!(fg::FigureGrid; position=:right, end """ - legend!(figpos, grid; kwargs...) + legend!(figpos, grid; order = nothing, kwargs...) Compute legend for `grid` (which should be the output of [`draw!`](@ref)) and draw it in -position `figpos`. Attributes allowed in `kwargs` are the same as `MakieLayout.Legend`. +position `figpos`. All `kwargs` are forwarded to Makie's `Legend` constructor. + +The order of scales represented in the legend can be changed with the `order` keyword. +By default, legend sections are ordered the same as they appear in the plot specification. +Assuming three scales `Color`, `MarkerSize` and `custom` exist in a spec, you can pass a vector +to reorder them like `[:MarkerSize, :custom, :Color]`, or merge multiple entries together with +a nested vector like `[[:MarkerSize, :custom], :Color]`, or give merged sections a title with the +pair syntax `[[:MarkerSize, :custom] => "Merged group", :Color]`. """ function legend!(figpos, grid; order = nothing, kwargs...) legend = compute_legend(grid; order) diff --git a/test/legend.jl b/test/legend.jl index c1a593f22..05cbf43c4 100644 --- a/test/legend.jl +++ b/test/legend.jl @@ -110,3 +110,33 @@ end @test length(leg_els) == 1 @test el_labels[] == last.(categories) end + +@testset "hidden legend" begin + df = (; + x = repeat(1:3, 3), + y = abs.(sin.(1:9)), + z=["a", "a", "a", "b", "b", "b", "c", "c", "c"] + ) + for show in [true, false] + fg = draw( + data(df) * mapping(:x, :y; stack=:z, color=:z) * visual(BarPlot), + legend = (; show) + ) + @test any(x -> x isa Legend, fg.figure.content) == show + end +end + +@testset "hidden colorbar" begin + df = (; + x = 1:3, + y = 4:6, + z = 7:9 + ) + for show in [true, false] + fg = draw( + data(df) * mapping(:x, :y; color=:z) * visual(BarPlot), + colorbar = (; show) + ) + @test any(x -> x isa Colorbar, fg.figure.content) == show + end +end