From 3c5d80cf7955eea92d90987c65161edecc401e4c Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:41:37 +0100 Subject: [PATCH 1/6] Allow functions as `labs(alt = ...)` input --- R/labels.r | 7 +++++-- man/labs.Rd | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/R/labels.r b/R/labels.r index 669db6b5fa..1c716f74ba 100644 --- a/R/labels.r +++ b/R/labels.r @@ -44,7 +44,9 @@ update_labels <- function(p, labels) { #' @param tag The text for the tag label which will be displayed at the #' top-left of the plot by default. #' @param alt,alt_insight Text used for the generation of alt-text for the plot. -#' See [get_alt_text] for examples. +#' See [get_alt_text] for examples. `alt` can also be a function that +#' takes the plot as input and returns text as output. `alt` also accepts +#' rlang [lambda][rlang::as_function()] function notation. #' @param ... A list of new name-value pairs. The name should be an aesthetic. #' @export #' @examples @@ -73,7 +75,8 @@ labs <- function(..., title = waiver(), subtitle = waiver(), caption = waiver(), tag = waiver(), alt = waiver(), alt_insight = waiver()) { # .ignore_empty = "all" is needed to allow trailing commas, which is NOT a trailing comma for dots_list() as it's in ... args <- dots_list(..., title = title, subtitle = subtitle, caption = caption, - tag = tag, alt = alt, alt_insight = alt_insight, .ignore_empty = "all") + tag = tag, alt = allow_lambda(alt), alt_insight = alt_insight, + .ignore_empty = "all") is_waive <- vapply(args, is.waive, logical(1)) args <- args[!is_waive] diff --git a/man/labs.Rd b/man/labs.Rd index d335f33f15..ff63ad7bd6 100644 --- a/man/labs.Rd +++ b/man/labs.Rd @@ -38,7 +38,9 @@ bottom-right of the plot by default.} top-left of the plot by default.} \item{alt, alt_insight}{Text used for the generation of alt-text for the plot. -See \link{get_alt_text} for examples.} +See \link{get_alt_text} for examples. \code{alt} can also be a function that +takes the plot as input and returns text as output. \code{alt} also accepts +rlang \link[rlang:as_function]{lambda} function notation.} \item{label}{The title of the respective axis (for \code{xlab()} or \code{ylab()}) or of the plot (for \code{ggtitle()}).} From 3c029534c90dbf342c809e8b224cce394d9b275c Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:42:09 +0100 Subject: [PATCH 2/6] Alt functions are called with plot as input --- R/labels.r | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/labels.r b/R/labels.r index 1c716f74ba..35557dbb5a 100644 --- a/R/labels.r +++ b/R/labels.r @@ -140,11 +140,13 @@ get_alt_text <- function(p, ...) { } #' @export get_alt_text.ggplot <- function(p, ...) { - p$labels[["alt"]] %||% "" + alt <- p$labels[["alt"]] %||% "" + if (is.function(alt)) alt(p) else alt } #' @export get_alt_text.ggplot_built <- function(p, ...) { - p$plot$labels[["alt"]] %||% "" + alt <- p$plot$labels[["alt"]] %||% "" + if (is.function(alt)) alt(p$plot) else alt } #' @export get_alt_text.gtable <- function(p, ...) { From eb02c0eb0eefeb2f1386725f3d40df51ae900df5 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:47:52 +0100 Subject: [PATCH 3/6] Add test for alt text functions --- tests/testthat/_snaps/labels.md | 7 +++++++ tests/testthat/test-labels.r | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/testthat/_snaps/labels.md diff --git a/tests/testthat/_snaps/labels.md b/tests/testthat/_snaps/labels.md new file mode 100644 index 0000000000..3d0d834223 --- /dev/null +++ b/tests/testthat/_snaps/labels.md @@ -0,0 +1,7 @@ +# alt text can take a function + + Code + get_alt_text(p) + Output + [1] "A plot showing class on the x-axis and count on the y-axis using a bar layer" + diff --git a/tests/testthat/test-labels.r b/tests/testthat/test-labels.r index 0e866fa2a4..dd2222fc69 100644 --- a/tests/testthat/test-labels.r +++ b/tests/testthat/test-labels.r @@ -69,6 +69,12 @@ test_that("alt text is returned", { expect_equal(get_alt_text(p), "An alt text") }) +test_that("alt text can take a function", { + p <- ggplot(mpg, aes(class)) + + geom_bar() + + labs(alt = ~ generate_alt_text(.x)) + expect_snapshot(get_alt_text(p)) +}) # Visual tests ------------------------------------------------------------ From c1d38ea45c2d43bfe14994feb93918a3d3edcf11 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:48:13 +0100 Subject: [PATCH 4/6] Add NEWS bullet --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 1b4dc36ba0..2d5100de2a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* A function can be provided to `labs(alt = <...>)` that takes the plot as input + and returns text as output (@teunbrand, #4795). * Fixed spurious warning when `weight` aesthetic was used in `stat_smooth()` (@teunbrand based on @clauswilke's suggestion, #5053). * The `lwd` alias now correctly replaced by `linewidth` instead of `size` From 5c5dac0e79b10f913510a0257fa246724d0fbad3 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Sat, 3 Dec 2022 14:11:47 +0100 Subject: [PATCH 5/6] Avoid recursion --- R/labels.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/labels.r b/R/labels.r index 35557dbb5a..30d40e61c1 100644 --- a/R/labels.r +++ b/R/labels.r @@ -141,11 +141,13 @@ get_alt_text <- function(p, ...) { #' @export get_alt_text.ggplot <- function(p, ...) { alt <- p$labels[["alt"]] %||% "" + p$labels[["alt"]] <- NULL if (is.function(alt)) alt(p) else alt } #' @export get_alt_text.ggplot_built <- function(p, ...) { alt <- p$plot$labels[["alt"]] %||% "" + p$plot$labels[["alt"]] <- NULL if (is.function(alt)) alt(p$plot) else alt } #' @export From 4910cc0e8f5e9946fde6b542341d1700f3595726 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 20 May 2024 10:13:54 +0200 Subject: [PATCH 6/6] deal with changes in {glue} --- R/labels.r | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/R/labels.r b/R/labels.r index 30d40e61c1..4f5ade202b 100644 --- a/R/labels.r +++ b/R/labels.r @@ -201,11 +201,16 @@ get_alt_text.gtable <- function(p, ...) { #' generate_alt_text <- function(p) { # Combine titles - title <- glue(glue_collapse( - sub("\\.?$", "", c(p$labels$title, p$labels$subtitle)), - last = ": " - ), ". ") - title <- safe_string(title) + if (!is.null(p$label$title %||% p$labels$subtitle)) { + title <- glue(glue_collapse( + sub("\\.?$", "", c(p$labels$title, p$labels$subtitle)), + last = ": " + ), ". ") + title <- safe_string(title) + } else { + title <- "" + } + # Get axes descriptions axes <- glue(" showing ", glue_collapse( @@ -222,7 +227,7 @@ generate_alt_text <- function(p) { if (length(layers) == 1) "a " else "", glue_collapse(layers, sep = ", ", last = " and "), " layer", - if (length(layers) == 1) "" else "s", + if (length(layers) == 1) "" else "s" ) layers <- safe_string(layers)