diff --git a/NEWS.md b/NEWS.md index 9d2a5eb033..e123a3a254 100644 --- a/NEWS.md +++ b/NEWS.md @@ -38,7 +38,9 @@ * `theme()` gets new `spacing` and `margins` arguments that all other spacings and (non-text) margins inherit from (@teunbrand, #5622). * `geom_ribbon()` can have varying `fill` or `alpha` in linear coordinate - systems (@teunbrand, #4690) + systems (@teunbrand, #4690). +* `geom_tile()` computes default widths and heights per panel instead of + per layer (@teunbrand, #5740). # ggplot2 3.5.1 diff --git a/R/geom-tile.R b/R/geom-tile.R index 139d6f733e..ad01b1248f 100644 --- a/R/geom-tile.R +++ b/R/geom-tile.R @@ -109,8 +109,11 @@ GeomTile <- ggproto("GeomTile", GeomRect, extra_params = c("na.rm"), setup_data = function(data, params) { - data$width <- data$width %||% params$width %||% resolution(data$x, FALSE, TRUE) - data$height <- data$height %||% params$height %||% resolution(data$y, FALSE, TRUE) + + data$width <- data$width %||% params$width %||% + stats::ave(data$x, data$PANEL, FUN = function(x) resolution(x, FALSE, TRUE)) + data$height <- data$height %||% params$height %||% + stats::ave(data$y, data$PANEL, FUN = function(y) resolution(y, FALSE, TRUE)) transform(data, xmin = x - width / 2, xmax = x + width / 2, width = NULL, diff --git a/tests/testthat/test-geom-tile.R b/tests/testthat/test-geom-tile.R index d0c8a6f073..f63602bf66 100644 --- a/tests/testthat/test-geom-tile.R +++ b/tests/testthat/test-geom-tile.R @@ -34,3 +34,18 @@ test_that("accepts linejoin parameter", { gp2 <- layer_grob(ggplot(df, aes(x, y)) + geom_tile(linejoin = "round"))[[1]]$gp expect_equal(gp2$linejoin, "round") }) + +test_that("width and height are inferred per panel", { + df <- data_frame0( + x = c(1, 2, 3, 10, 20, 30), + y = c(10, 10.5, 11, 100, 200, 300), + f = rep(c("A", "B"), each = 3) + ) + + ld <- layer_data( + ggplot(df, aes(x, y)) + geom_tile() + facet_wrap(~f, scales = "free") + ) + + expect_equal(ld$xmax - ld$xmin, c(1, 1, 1, 10, 10, 10)) + expect_equal(ld$ymax - ld$ymin, c(0.5, 0.5, 0.5, 100, 100, 100)) +})