Changelog
Source:NEWS.md
ggguides 1.1.10
Bug Fixes
-
legend_style(by = <aes>, justification = ...)collided when two or more legends shared the same edge. The 1.1.9 fix routed each call to a single globaltheme(legend.justification.<side> = ...), so the second call overwrote the first —legend_style(by = "colour", justification = "left") + legend_style(by = "fill", justification = "right")on the top edge ended up with both legends pinned to the right. Per-legend justification now also stashes the requested rail position on the plot and rewrites theguide-box-<side>internal gtable at render time so each legend sits at its own fraction of the rail. The render-time path also reorders the guides so the gtable cell order matches the requested rail order. The global theme write is kept as a fallback for the single-legend case. (reported by Youtao)
Internal
The render-time gtable post-processor checks ggplot2’s guide-box layout shape (column count and pad-cell unit type) and falls back to the previous behavior with a one-shot warning if it doesn’t match what ggguides was tested against (currently ggplot2 4.0.3) — so a future ggplot2 internal change degrades gracefully instead of producing wrong output.
If a guide already has an explicit
guide_legend(order = N)set, per-legend justification reordering on that side is skipped and a warning is emitted, so the user-supplied order is never silently overwritten.
ggguides 1.1.9
Bug Fixes
legend_style(by = <aes>, justification = ...)had no visible effect. The update attached the justification to the guide’s embedded theme viaguide_legend(theme = theme(legend.justification.<side> = ...)), but ggplot2 >= 3.5 does not consult the side-specific justification elements inside a guide’s embedded theme — only the whole-plot theme is read. Legends stayed centered along their rail regardless of thejustificationvalue. The NEWS entry for 1.1.5 that introduced this argument was therefore incorrect: the workaround Youtao documented,theme(legend.justification.<side> = ...), was the only thing that actually worked. 1.1.9 fixes this by routing per-guidejustificationto a whole-plot theme element keyed on the guide’s resolved side, solegend_top(by = "colour") + legend_style(by = "colour", justification = "left")now slides the colour legend to the left end of the top rail as documented. If you had atheme(legend.justification.<side> = ...)workaround in your code, you can remove it. (reported by Youtao)legend_style(justification = ...)withoutbywas writing to the genericlegend.justification, which ggplot2 coerces per axis and mis-maps mixed-axis scalars (e.g.,"left"on a vertical rail becomes0— bottom). It now writes to the side-specific theme elements (legend.justification.top/.bottomfor horizontal scalars;legend.justification.left/.rightfor vertical scalars; all four for"center"and numerics).
ggguides 1.1.8
Bug Fixes
-
legend_left(),legend_right(),legend_top(), andlegend_bottom()were writing tolegend.justification, the generic fallback element. In ggplot2 >= 3.5.0 each side has its own element —legend.justification.left,legend.justification.right,legend.justification.top,legend.justification.bottom— and the generic fallback is silently coerced per axis.legend_left()in particular was sending"left"to a vertical rail, which ggplot2 coerced to0(bottom), so the legend was actually pinned to the bottom of the left edge when users expected it centered. The four side functions now write to the side-specific element and default to"center", which is what the documentation has always described. (reported by Youtao)
New Features
-
legend_left(),legend_right(),legend_top(), andlegend_bottom()gain ajustificationargument. It slides the legend along its rail:"top"/"center"/"bottom"(or a number in[0, 1]) for left/right,"left"/"center"/"right"for top/bottom. This is the side-legend counterpart tolegend_inside(justification = ...). For per-guide control when several legends sit on different sides, keep usinglegend_style(by = ..., justification = ...).
Documentation
-
?legend_left(and the three siblings) now explain the “rail” semantics and note the naming asymmetry withlegend_inside(): on a side, the justification keyword refers to where the legend sits along the panel edge; inside, it refers to which corner of the legend anchors to the(x, y)position.
ggguides 1.1.7
Bug Fixes
-
legend_inside(justification = ...)had no visible effect because the function was writing tolegend.justification— the theme element that anchors side legends. In ggplot2 >= 3.5.0 the anchor forlegend.position = "inside"is a separate element,legend.justification.inside.legend_inside()now writes to that element, so thejustificationargument (and the justifications implied byposition = "topright","bottomleft", etc.) move the legend as documented. Users who had been working around the bug withtheme(legend.justification = ...)should remove that override. (reported by Youtao)
ggguides 1.1.6
CRAN release: 2026-04-23
Bug Fixes
-
legend_*(by = <aes>)andlegend_style(by = <aes>)now compose correctly when chained for the same aesthetic. Previously, each call built a freshguide_legend()that replaced the prior one, solegend_top(by = "colour") + legend_style(by = "colour", margin = ...)silently reset the colour legend’s position back to the plot default. The per-aesthetic helpers now return a ggguides update object whoseggplot_addmethod merges new params into the existing guide. This fixes the “Four Legends, One per Side” vignette example. (reported by Youtao)
API Consistency
-
legend_inside(): renamedjustargument tojustificationfor consistency withlegend_style(justification = ...)and ggplot2’slegend.justificationtheme element. The oldjustname still works but emits a deprecation warning.
ggguides 1.1.5
CRAN release: 2026-04-22
New Features
-
legend_style()gains ajustificationargument. Withby = NULLit setslegend.justificationglobally; withby = "<aes>"it slides a single legend along its side viaguide_legend(theme = ...). Useful when four legends sit on four different sides and each needs its own alignment.
ggguides 1.1.4
CRAN release: 2026-01-09
ggguides 1.1.2
Bug Fixes
- Fixed
get_legend()returning empty grob with ggplot2 3.5.0+ (guide-box naming changed to position-specific names like “guide-box-right”)
ggguides 1.1.0
CRAN Submission
- Added
@returndocumentation to all S3 methods (ggplot_add, print, plot, and ggplotGrob methods) - Changed
\dontrun{}to\donttest{}in examples that require suggested packages
Documentation
legend_keys(): Added detailed documentation explaining how to use filled shapes (21-25) with different outline/fill color combinations. Clarified that “colored fill with black outline” requires mapping bothcolorandfillaesthetics in the original plot (#1).Added new example showing correct usage for colored fills with black outlines.