Skip to content

Alt text label can be function #5079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -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).
* Position scales combined with `coord_sf()` can now use functions in the
`breaks` argument. In addition, `n.breaks` works as intended and
`breaks = NULL` removes grid lines and axes (@teunbrand, #4622).
Expand Down
32 changes: 22 additions & 10 deletions R/labels.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
#' @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
#'
Expand Down Expand Up @@ -76,7 +78,8 @@
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]
Expand Down Expand Up @@ -140,11 +143,15 @@
}
#' @export
get_alt_text.ggplot <- function(p, ...) {
p$labels[["alt"]] %||% ""
alt <- p$labels[["alt"]] %||% ""
p$labels[["alt"]] <- NULL
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"]] %||% ""
p$plot$labels[["alt"]] <- NULL
if (is.function(alt)) alt(p$plot) else alt

Check warning on line 154 in R/labels.R

View check run for this annotation

Codecov / codecov/patch

R/labels.R#L152-L154

Added lines #L152 - L154 were not covered by tests
}
#' @export
get_alt_text.gtable <- function(p, ...) {
Expand Down Expand Up @@ -197,11 +204,16 @@
#'
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 = ": "

Check warning on line 210 in R/labels.R

View check run for this annotation

Codecov / codecov/patch

R/labels.R#L208-L210

Added lines #L208 - L210 were not covered by tests
), ". ")
title <- safe_string(title)

Check warning on line 212 in R/labels.R

View check run for this annotation

Codecov / codecov/patch

R/labels.R#L212

Added line #L212 was not covered by tests
} else {
title <- ""
}


# Get axes descriptions
axes <- glue(" showing ", glue_collapse(
Expand All @@ -218,7 +230,7 @@
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)

Expand Down
4 changes: 3 additions & 1 deletion man/labs.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions tests/testthat/_snaps/labels.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 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"

# plot.tag.position rejects invalid input

The `plot.tag.position` theme element must be a <character/numeric/integer> object.
Expand Down
6 changes: 6 additions & 0 deletions tests/testthat/test-labels.R
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})

test_that("plot.tag.position rejects invalid input", {
p <- ggplot(mtcars, aes(mpg, disp)) + geom_point() + labs(tag = "Fig. A)")
Expand Down
Loading