-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stretching legends #5515
Stretching legends #5515
Conversation
width = 1, | ||
height = 1, | ||
default.units = "npc", | ||
gp = gpar(col = NA), | ||
interpolate = TRUE | ||
) | ||
} else{ | ||
if (params$direction == "horizontal") { | ||
width <- elements$key.width / nrow(decor) | ||
height <- elements$key.height | ||
width <- 1 / nrow(decor) | ||
height <- 1 | ||
x <- (seq(nrow(decor)) - 1) * width | ||
y <- 0 | ||
} else { | ||
width <- elements$key.width | ||
height <- elements$key.height / nrow(decor) | ||
width <- 1 | ||
height <- 1 / nrow(decor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting these sizes to npcs is benign because the actual size is set in Guide$measure_grobs()
.
widths <- unit(c(sizes$padding[4], sizes$widths, sizes$padding[2]), "cm") | ||
if (is.unit(params$keywidth) && unitType(params$keywidth) == "null") { | ||
i <- unique(layout$layout$key_col) | ||
widths[i] <- params$keywidth | ||
} | ||
|
||
gt <- gtable( | ||
widths = unit(c(sizes$padding[4], sizes$widths, sizes$padding[2]), "cm"), | ||
heights = unit(c(sizes$padding[1], sizes$heights, sizes$padding[3]), "cm") | ||
) | ||
heights <- unit(c(sizes$padding[1], sizes$heights, sizes$padding[3]), "cm") | ||
if (is.unit(params$keyheight) && unitType(params$keyheight) == "null") { | ||
i <- unique(layout$layout$key_row) | ||
heights[i] <- params$keyheight | ||
} | ||
|
||
gt <- gtable(widths = widths, heights = heights) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is step 1
Merge branch 'main' into flex_legend_size # Conflicts: # R/guide-legend.R # R/guides-.R # R/plot-build.R
What I previously called step 2 and 3 are now all part of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks for the review Thomas! I sneaked in a little fix related to an interaction with #5570 I ran into, but I'll merge anyway because it I'm pretty sure the fix can't harm anything. |
This PR aims to fix #4896.
Briefly it allows
keywidth
/keyheight
andbarwidth
/barheight
to be 'null' units, which fills the legends to the available space.In somewhat more detail, 'null' in grid units are typically (to my understanding) interpreted as 'calculate all other units first, then divide the remaining space among the null units'. In this PR, I propagate that behaviour for legend key sizes. This works in several steps:
Guide$assemble_drawing()
stage that the key sizes are replaced with the provided 'null' units if provided by the user in theguide_*()
function (i.e., we don't propagate 'null' units set in the theme).ggplot_gtable()
, the legend size is set to 1npc if 'sum' units are encountered in the legend size. These 'sum' units should only appear when a 'null' had been set somewhere, because everything else in legends is casted to centimeters. This aligns the stretched legends to the panel.I didn't want to mess with the guts of
<unit>
objects too much, so at several places I just delay taking the sum of units to look into their types. I had to improvise aunitType
function for R <4.0, which works, but might not be great. In any case, in 2024 the minimum supported version of R should be R 4.0, so this might not matter for much longer.I've marked this option as 'experimental' in the documentation, just to prepare users for the possibility that there might be unexpected behaviour that I cannot foresee at this point.
On to examples: if we want to implement #4896, we want to might want to start like this:
This isn't quite what the result should be, so we'd have to set the legend margins to 0 and remove the title to get full alignment.
This shows a stretched colourbar:
This shows a stretched legend:
The behaviour when you combine an absolute legend and relative legend follows the 'null' heuristics described above: first absolute units are honoured, then remainder is divided among null units.
When you just have 1 legend, the value of the 'null' unit doesn't matter, but it can come in handy when combining legends and you want to give them a different size.
It was not really clear to me what should happen when the opposite size (that isn't parallel to the panel side) is set as a null unit, since there isn't any 'available space' to stretch into. With the current code, the 'available space' is 0, so the guide is shrunk. Note that this exactly the same as it works in CRAN ggplot2, so this isn't a regression.
Created on 2023-11-09 with reprex v2.0.2