Skip to content

Commit 3e10662

Browse files
authored
Remove aspect ratio warning when using theme(panel.widths, panel.heights) (#6708)
* remove aspect ratio warning * Add note in docs * Try to preserve aspect ratio * ensure scalar width/height when preserving aspect ratio * document new behaviour * add test for behaviour * add news bullet
1 parent 5663e3d commit 3e10662

File tree

5 files changed

+54
-16
lines changed

5 files changed

+54
-16
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
legend glyphs (@teunbrand, #6594)
2727
* Fixed regression where `NULL`-aesthetics contributed to plot labels too
2828
insistently. Now they contribute only as fallback labels (@teunbrand, #6616)
29+
* The `theme(panel.widths, panel.heights)` setting attempts to preserve the
30+
plot's aspect ratio when only one of the two settings is given, and the plot
31+
has a single panel (@teunbrand, #6701).
2932
* Fixed axis misplacement in `coor_radial()` when labels are blank (@teunbrand, #6574)
3033

3134
# ggplot2 4.0.0

R/facet-.R

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -731,18 +731,24 @@ Facet <- ggproto("Facet", NULL,
731731
return(table)
732732
}
733733

734-
if (isTRUE(table$respect)) {
735-
args <- !c(is.null(new_widths), is.null(new_heights))
736-
args <- c("panel.widths", "panel.heights")[args]
737-
cli::cli_warn(
738-
"Aspect ratios are overruled by {.arg {args}} theme element{?s}."
739-
)
740-
table$respect <- FALSE
741-
}
742-
743734
rows <- panel_rows(table)
744735
cols <- panel_cols(table)
745736

737+
if (isTRUE(table$respect) && # Has fixed aspect ratio
738+
xor(is.null(new_widths), is.null(new_heights)) && # One dimension is set
739+
nrow(rows) == 1 && nrow(cols) == 1) { # Just a single panel
740+
old_width <- table$widths[cols$l]
741+
old_height <- table$heights[rows$t]
742+
# Try to reconstruct aspect ratio from panel size
743+
# We shouldn't attempt this with mixed or compound (e.g. "sum") units
744+
if (identical(unitType(old_width), "null") &&
745+
identical(unitType(old_height), "null")) {
746+
ratio <- as.numeric(old_height) / as.numeric(old_width)
747+
new_widths <- (new_widths %||% (new_heights / ratio))[1]
748+
new_heights <- (new_heights %||% (new_widths * ratio))[1]
749+
}
750+
}
751+
746752
if (length(new_widths) == 1L && nrow(cols) > 1L) {
747753
# Get total size of non-panel widths in between panels
748754
extra <- setdiff(seq(min(cols$l), max(cols$r)), union(cols$l, cols$r))

R/theme.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,10 @@
151151
#' from `line`
152152
#' @param panel.widths,panel.heights Sizes for panels (`units`). Can be a
153153
#' single unit to set the total size for the panel area, or a unit vector to
154-
#' set the size of individual panels.
154+
#' set the size of individual panels. Using this setting overrides the
155+
#' aspect ratio set by the theme, coord or facets. An exception is made when
156+
#' the plot has a single panel and exactly one of the width *or* height is
157+
#' set, in which case an attempt is made to preserve the aspect ratio.
155158
#' @param panel.ontop option to place the panel (background, gridlines) over
156159
#' the data layers (`logical`). Usually used with a transparent or blank
157160
#' `panel.background`.

man/theme.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-theme.R

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -717,11 +717,34 @@ test_that("panel.widths and panel.heights works with free-space panels", {
717717

718718
})
719719

720-
test_that("panel.widths and panel.heights appropriately warn about aspect override", {
721-
p <- ggplot(mpg, aes(displ, hwy)) +
722-
geom_point() +
723-
theme(aspect.ratio = 1, panel.widths = unit(4, "cm"))
724-
expect_warning(ggplotGrob(p), "Aspect ratios are overruled")
720+
test_that("panel.withs and panel.heights preserve aspect ratios with single panels", {
721+
722+
df <- data.frame(x = c(1, 2))
723+
724+
p <- ggplotGrob(
725+
ggplot(df, aes(x, x)) +
726+
geom_point() +
727+
theme(
728+
aspect.ratio = 2,
729+
panel.heights = unit(10, "cm")
730+
)
731+
)
732+
733+
width <- p$widths[panel_cols(p)$l]
734+
expect_equal(as.character(width), "5cm")
735+
736+
p <- ggplotGrob(
737+
ggplot(df, aes(x, x)) +
738+
geom_point() +
739+
facet_wrap(~ x) + # This behaviour doesn't occur in multipanel plots.
740+
theme(
741+
aspect.ratio = 2,
742+
panel.heights = unit(10, "cm")
743+
)
744+
)
745+
746+
width <- p$widths[panel_cols(p)$l]
747+
expect_equal(as.character(width), c("1null", "1null"))
725748
})
726749

727750
test_that("margin_part() mechanics work as expected", {

0 commit comments

Comments
 (0)