From dc59bd7a354153e672cf67d9f9c0c744f9944f05 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Thu, 4 Apr 2024 16:09:45 +0200 Subject: [PATCH 1/5] Don't fix viewport size --- R/guide-axis.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/guide-axis.R b/R/guide-axis.R index 22cda82454..de7fb9e9d4 100644 --- a/R/guide-axis.R +++ b/R/guide-axis.R @@ -430,7 +430,6 @@ GuideAxis <- ggproto( vp <- exec( viewport, !!params$orth_aes := unit(params$orth_side, "npc"), - !!params$orth_size := params$measure_gtable(gt), just = params$opposite ) From 6cfff35718c4de7239b77dad42bd1c0e3797e2f4 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Thu, 4 Apr 2024 16:09:55 +0200 Subject: [PATCH 2/5] add null padding --- R/guide-axis.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/R/guide-axis.R b/R/guide-axis.R index de7fb9e9d4..063e6178c3 100644 --- a/R/guide-axis.R +++ b/R/guide-axis.R @@ -409,6 +409,7 @@ GuideAxis <- ggproto( # Unlist the 'label' grobs z <- if (params$position == "left") c(2, 1, 3) else 1:3 z <- rep(z, c(1, length(grobs$labels), 1)) + has_labels <- !is.zero(grobs$labels[[1]]) grobs <- c(list(grobs$ticks), grobs$labels, list(grobs$title)) # Initialise empty gtable @@ -433,6 +434,21 @@ GuideAxis <- ggproto( just = params$opposite ) + # Add null-unit padding to justify based on eventual gtable cell shape + # rather than dimensions of this axis alone. + if (has_labels && params$position %in% c("left", "right")) { + where <- layout$l[-c(1, length(layout$l))] + just <- with(elements$text, rotate_just(angle, hjust, vjust))$hjust %||% 0.5 + gt <- gtable_add_cols(gt, unit(just, "null"), pos = min(where) - 1) + gt <- gtable_add_cols(gt, unit(1 - just, "null"), pos = max(where) + 1) + } + if (has_labels && params$position %in% c("top", "bottom")) { + where <- layout$t[-c(1, length(layout$t))] + just <- with(elements$text, rotate_just(angle, hjust, vjust))$vjust %||% 0.5 + gt <- gtable_add_rows(gt, unit(1 - just, "null"), pos = min(where) - 1) + gt <- gtable_add_rows(gt, unit(just, "null"), pos = max(where) + 1) + } + # Assemble with axis line absoluteGrob( gList(axis_line, gt), From 320bf6c6393a173109652082f66d77aed2a9e949 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Thu, 4 Apr 2024 16:48:05 +0200 Subject: [PATCH 3/5] Fix viewport size, but flexibly --- R/guide-axis.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/guide-axis.R b/R/guide-axis.R index 063e6178c3..784b95b69a 100644 --- a/R/guide-axis.R +++ b/R/guide-axis.R @@ -431,6 +431,7 @@ GuideAxis <- ggproto( vp <- exec( viewport, !!params$orth_aes := unit(params$orth_side, "npc"), + !!params$orth_size := max(params$measure_gtable(gt), unit(1, "npc")), just = params$opposite ) From 72015358ba28dff6abcdf13164fa7be76c304a4a Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 20 Aug 2024 09:21:20 +0200 Subject: [PATCH 4/5] add test --- .../facet-labels/outside-justified-labels.svg | 144 ++++++++++++++++++ tests/testthat/test-facet-labels.R | 27 ++++ 2 files changed, 171 insertions(+) create mode 100644 tests/testthat/_snaps/facet-labels/outside-justified-labels.svg diff --git a/tests/testthat/_snaps/facet-labels/outside-justified-labels.svg b/tests/testthat/_snaps/facet-labels/outside-justified-labels.svg new file mode 100644 index 0000000000..9b04f0b614 --- /dev/null +++ b/tests/testthat/_snaps/facet-labels/outside-justified-labels.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +C + + + + + + + + + + +D + + + + + + + + + + +A + + + + + + + + + + +B + + + +X +X +X +X +X + +X + +X +X +X +X +X + +X +YYYYY + +Y + + +YYYYY + +Y +x +y +outside-justified labels + + diff --git a/tests/testthat/test-facet-labels.R b/tests/testthat/test-facet-labels.R index 6d086e0b7b..c8613bc978 100644 --- a/tests/testthat/test-facet-labels.R +++ b/tests/testthat/test-facet-labels.R @@ -157,3 +157,30 @@ test_that("parsed labels are rendered correctly", { facet_wrap(~ f, labeller = label_parsed) ) }) + +test_that("outside-justified labels are justified across panels", { + + df <- data.frame( + x = c("X\nX\nX\nX\nX", "X"), + y = c("YYYYY", "Y"), + f1 = c("A", "B"), + f2 = c("C", "D") + ) + + # By default, axis labels are inside-justified so it doesn't matter whether + # justification occurs across panels. This changes for outside-justification. + # See #5820 + + p <- ggplot(df, aes(x, y)) + + geom_point() + + facet_grid(f1 ~ f2, scales = "free") + + guides(x.sec = "axis", y.sec = "axis") + + theme( + axis.text.y.left = element_text(hjust = 0), + axis.text.y.right = element_text(hjust = 1), + axis.text.x.top = element_text(vjust = 1), + axis.text.x.bottom = element_text(vjust = 0) + ) + + expect_doppelganger("outside-justified labels", p) +}) From 1ae57c21b74e01af3acf52f21bd5767b7973c213 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 20 Aug 2024 09:22:43 +0200 Subject: [PATCH 5/5] add news bullet --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index f9bdc996e0..807e9a00fd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # ggplot2 (development version) +* Axis labels are now justified across facet panels (@teunbrand, #5820) * Fixed bug in `stat_function()` so x-axis title now produced automatically when no data added. (@phispu, #5647). * geom_sf now accepts shape names (@sierrajohnson, #5808)