Skip to content

Commit d16c067

Browse files
authored
Relative legend spacing (#6431)
* allow for relative `spacing` in `redistribute_null_units()` * null spacing counts as stretchy legends * dismiss global margins when stretchy * add test * add news bullet * actually test the thing we say we're testing
1 parent 8c86d97 commit d16c067

File tree

5 files changed

+246
-21
lines changed

5 files changed

+246
-21
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@
353353
(@teunbrand, #6269).
354354
* The default colour and fill scales have a new `palette` argument
355355
(@teunbrand, #6064).
356+
* The `theme(legend.spacing.{x/y})` setting now accepts `null`-units
357+
(@teunbrand, #6417).
356358

357359
# ggplot2 3.5.2
358360

R/guides-.R

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,14 @@ Guides <- ggproto(
653653
height = heightDetails(grobs[[i]]))
654654
)
655655
}
656-
657-
spacing <- convertWidth(theme$legend.spacing.x, "cm")
656+
spacing <- theme$legend.spacing.x
657+
stretch_spacing <- any(unitType(spacing) == "null")
658+
if (!stretch_spacing) {
659+
spacing <- convertWidth(spacing, "cm")
660+
}
658661
heights <- unit(height_cm(lapply(heights, sum)), "cm")
659662

660-
if (stretch_x) {
663+
if (stretch_x || stretch_spacing) {
661664
widths <- redistribute_null_units(widths, spacing, margin, "width")
662665
vp_width <- unit(1, "npc")
663666
} else {
@@ -692,10 +695,14 @@ Guides <- ggproto(
692695
)
693696
}
694697

695-
spacing <- convertHeight(theme$legend.spacing.y, "cm")
698+
spacing <- theme$legend.spacing.y
699+
stretch_spacing <- any(unitType(spacing) == "null")
700+
if (!stretch_spacing) {
701+
spacing <- convertWidth(spacing, "cm")
702+
}
696703
widths <- unit(width_cm(lapply(widths, sum)), "cm")
697704

698-
if (stretch_y) {
705+
if (stretch_y || stretch_spacing) {
699706
heights <- redistribute_null_units(heights, spacing, margin, "height")
700707
vp_height <- unit(1, "npc")
701708
} else {
@@ -735,10 +742,10 @@ Guides <- ggproto(
735742
)
736743

737744
# Set global margin
738-
if (stretch_x) {
745+
if (stretch_x || stretch_spacing) {
739746
global_margin[c(2, 4)] <- unit(0, "cm")
740747
}
741-
if (stretch_y) {
748+
if (stretch_y || stretch_spacing) {
742749
global_margin[c(1, 3)] <- unit(0, "cm")
743750
}
744751
guides <- gtable_add_padding(guides, global_margin)
@@ -933,26 +940,20 @@ redistribute_null_units <- function(units, spacing, margin, type = "width") {
933940
}
934941

935942
# Get spacing between guides and margins in absolute units
936-
size <- switch(type, width = convertWidth, height = convertHeight)
937-
spacing <- size(spacing, "cm", valueOnly = TRUE)
938-
spacing <- sum(rep(spacing, length(units) - 1))
943+
size <- switch(type, width = width_cm, height = height_cm)
944+
spacing <- sum(rep(spacing, length.out = length(units) - 1))
939945
margin <- switch(type, width = margin[c(2, 4)], height = margin[c(1, 3)])
940-
margin <- sum(size(margin, "cm", valueOnly = TRUE))
946+
margin <- sum(size(margin))
941947

942948
# Get the absolute parts of the unit
943-
absolute <- vapply(units, function(u) {
944-
u <- absolute.size(u)
945-
u <- size(u, "cm", valueOnly = TRUE)
946-
sum(u)
947-
}, numeric(1))
948-
absolute_sum <- sum(absolute) + spacing + margin
949+
absolute <- vapply(units, function(u) sum(size(absolute.size(u))), numeric(1))
950+
absolute_sum <- sum(absolute) + sum(size(spacing)) + margin
949951

950952
# Get the null parts of the unit
953+
num_null <- function(x) sum(as.numeric(x)[unitType(x) == "null"])
951954
relative <- rep(0, length(units))
952-
relative[has_null] <- vapply(units[has_null], function(u) {
953-
sum(as.numeric(u)[unitType(u) == "null"])
954-
}, numeric(1))
955-
relative_sum <- sum(relative)
955+
relative[has_null] <- vapply(units[has_null], num_null, numeric(1))
956+
relative_sum <- sum(relative) + num_null(spacing)
956957

957958
if (relative_sum == 0) {
958959
return(unit(absolute, "cm"))
Lines changed: 100 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)