From 78be71d3b976081d77efb8a3813f0f1b6d878be4 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Wed, 24 Sep 2025 18:42:40 +0200 Subject: [PATCH 1/7] labels derived from NULL aesthetics serve only as fallback labels --- R/aes-evaluation.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/aes-evaluation.R b/R/aes-evaluation.R index e29d0c5d25..2a7a69d382 100644 --- a/R/aes-evaluation.R +++ b/R/aes-evaluation.R @@ -350,7 +350,10 @@ strip_stage <- function(expr) { make_labels <- function(mapping) { default_label <- function(aesthetic, mapping) { # e.g., geom_smooth(aes(colour = "loess")) or aes(y = NULL) - if (is.null(mapping) || is.atomic(mapping)) { + if (is.null(mapping)) { + return(structure(aesthetic, fallback = TRUE)) + } + if (is.atomic(mapping)) { return(aesthetic) } mapping <- strip_stage(mapping) From 2a8cd27485c4ac91da2b5fc1ebc93277fe2de588 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Wed, 24 Sep 2025 18:43:53 +0200 Subject: [PATCH 2/7] catch tests where this occurs --- tests/testthat/test-aes-calculated.R | 6 +++++- tests/testthat/test-aes.R | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-aes-calculated.R b/tests/testthat/test-aes-calculated.R index 2d389106cf..297ac0b171 100644 --- a/tests/testthat/test-aes-calculated.R +++ b/tests/testthat/test-aes-calculated.R @@ -47,7 +47,11 @@ test_that("make_labels() deparses mappings properly", { expect_match(x_lab, "...$") # if the mapping is a literal or NULL, the aesthetics is used expect_identical(make_labels(aes(x = 1)), list(x = "x")) - expect_identical(make_labels(aes(x = NULL)), list(x = "x")) + # NULL labels should only be used as fallback labels + expect_identical( + make_labels(aes(x = NULL)), + list(x = structure("x", fallback = TRUE)) + ) }) test_that("staged aesthetics warn appropriately for duplicated names", { diff --git a/tests/testthat/test-aes.R b/tests/testthat/test-aes.R index b0922383cc..c3786e3975 100644 --- a/tests/testthat/test-aes.R +++ b/tests/testthat/test-aes.R @@ -103,7 +103,8 @@ test_that("quosures are squashed when creating default label for a mapping", { test_that("labelling doesn't cause error if aesthetic is NULL", { p <- ggplot(mtcars) + aes(x = NULL) labels <- ggplot_build(p)@plot@labels - expect_identical(labels$x, "x") + # NULL labels should only be used as fallback labels + expect_identical(labels$x, structure("x", fallback = TRUE)) }) test_that("aes standardises aesthetic names", { From aa762b510333bec30be55a004438624aa8b66478 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Wed, 24 Sep 2025 18:46:20 +0200 Subject: [PATCH 3/7] add news bullet --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 0fd950dcf6..019a4c2e3f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ### Bug fixes +* Fixed regression where `NULL`-aesthetics contributed to plot labels too + insistently. Now they contribute only as fallback labels (@teunbrand, #6616) * Fixed regression where `draw_key_rect()` stopped using `fill` colours (@mitchelloharawild, #6609). * Fixed regression where `scale_{x,y}_*()` threw an error when an expression From c19876cb902a4a985177d8e8a99d0a20b40f3a4d Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 7 Oct 2025 16:35:13 +0200 Subject: [PATCH 4/7] atomic vectors also produce fallback labels --- R/aes-evaluation.R | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/R/aes-evaluation.R b/R/aes-evaluation.R index 2a7a69d382..37d4f08061 100644 --- a/R/aes-evaluation.R +++ b/R/aes-evaluation.R @@ -350,12 +350,9 @@ strip_stage <- function(expr) { make_labels <- function(mapping) { default_label <- function(aesthetic, mapping) { # e.g., geom_smooth(aes(colour = "loess")) or aes(y = NULL) - if (is.null(mapping)) { + if (is.null(mapping) || is.atomic(mapping)) { return(structure(aesthetic, fallback = TRUE)) } - if (is.atomic(mapping)) { - return(aesthetic) - } mapping <- strip_stage(mapping) mapping <- strip_dots(mapping, strip_pronoun = TRUE) if (is_quosure(mapping) && quo_is_symbol(mapping)) { From 4fcdc3710d6468bc8fc8e4d6681e7ab910a77ffd Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 7 Oct 2025 16:37:21 +0200 Subject: [PATCH 5/7] move `make_labels()` helper to file where it is used --- R/aes-evaluation.R | 20 -------------------- R/labels.R | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/R/aes-evaluation.R b/R/aes-evaluation.R index 37d4f08061..f906d4bc2d 100644 --- a/R/aes-evaluation.R +++ b/R/aes-evaluation.R @@ -346,26 +346,6 @@ strip_stage <- function(expr) { } } -# Convert aesthetic mapping into text labels -make_labels <- function(mapping) { - default_label <- function(aesthetic, mapping) { - # e.g., geom_smooth(aes(colour = "loess")) or aes(y = NULL) - if (is.null(mapping) || is.atomic(mapping)) { - return(structure(aesthetic, fallback = TRUE)) - } - mapping <- strip_stage(mapping) - mapping <- strip_dots(mapping, strip_pronoun = TRUE) - if (is_quosure(mapping) && quo_is_symbol(mapping)) { - name <- as_string(quo_get_expr(mapping)) - } else { - name <- quo_text(mapping) - name <- gsub("\n.*$", "...", name) - } - name - } - Map(default_label, names(mapping), mapping) -} - eval_aesthetics <- function(aesthetics, data, mask = NULL) { env <- child_env(base_env()) diff --git a/R/labels.R b/R/labels.R index a0991fed03..d5f7706d82 100644 --- a/R/labels.R +++ b/R/labels.R @@ -120,6 +120,26 @@ setup_plot_labels <- function(plot, layers, data) { labs(!!!defaults(plot_labels, labels)) } +# Convert aesthetic mapping into text labels +make_labels <- function(mapping) { + default_label <- function(aesthetic, mapping) { + # e.g., geom_smooth(aes(colour = "loess")) or aes(y = NULL) + if (is.null(mapping) || is.atomic(mapping)) { + return(structure(aesthetic, fallback = TRUE)) + } + mapping <- strip_stage(mapping) + mapping <- strip_dots(mapping, strip_pronoun = TRUE) + if (is_quosure(mapping) && quo_is_symbol(mapping)) { + name <- as_string(quo_get_expr(mapping)) + } else { + name <- quo_text(mapping) + name <- gsub("\n.*$", "...", name) + } + name + } + Map(default_label, names(mapping), mapping) +} + #' Modify axis, legend, and plot labels #' #' Good labels are critical for making your plots accessible to a wider From 54d2b3f55fe87efcf293dd8f0c63f0c05666541d Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 7 Oct 2025 16:39:37 +0200 Subject: [PATCH 6/7] update test --- tests/testthat/test-aes-calculated.R | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/testthat/test-aes-calculated.R b/tests/testthat/test-aes-calculated.R index 297ac0b171..ee922ba005 100644 --- a/tests/testthat/test-aes-calculated.R +++ b/tests/testthat/test-aes-calculated.R @@ -45,13 +45,11 @@ test_that("make_labels() deparses mappings properly", { x_lab <- make_labels(aes(x = 2 * x * exp(`coef 1` * x^2) * 2 * x * exp(`coef 1` * x^2) * 2 * x))$x expect_length(x_lab, 1L) expect_match(x_lab, "...$") - # if the mapping is a literal or NULL, the aesthetics is used - expect_identical(make_labels(aes(x = 1)), list(x = "x")) + fallback <- list(x = structure("x", fallback = TRUE)) + # if the mapping is a literal or NULL, the aesthetics is used as fallback + expect_identical(make_labels(aes(x = 1)), fallback) # NULL labels should only be used as fallback labels - expect_identical( - make_labels(aes(x = NULL)), - list(x = structure("x", fallback = TRUE)) - ) + expect_identical(make_labels(aes(x = NULL)), fallback) }) test_that("staged aesthetics warn appropriately for duplicated names", { From 7b751d0c1cf648e19b8b792522f52a7bcaeb6752 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 7 Oct 2025 16:40:54 +0200 Subject: [PATCH 7/7] fix guide order in unrelated test --- tests/testthat/test-draw-key.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-draw-key.R b/tests/testthat/test-draw-key.R index 223bfd6d5c..511077d0a1 100644 --- a/tests/testthat/test-draw-key.R +++ b/tests/testthat/test-draw-key.R @@ -110,7 +110,11 @@ test_that("keep_draw_key", { aes(colour = "line", alpha = "line"), show.legend = c("colour" = NA, alpha = TRUE) ) + - suppressWarnings(scale_alpha_discrete()) + suppressWarnings(scale_alpha_discrete()) + + guides( + alpha = guide_legend(order = 1), + colour = guide_legend(order = 2) + ) expect_doppelganger("appropriate colour key with alpha key as lines", p)