tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.39k stars 2k forks source link

Default labels from attributes (option 2) #5879

Open teunbrand opened 2 months ago

teunbrand commented 2 months ago

This PR aims to fix #4631 and fix #5894 and competes with #5878.

Briefly, this is also an attempt to derive default labels from the 'label' attribute.

In contrast to #5878, this resolves labels in the ggplot_build() stage, thereby circumventing some limitations of that approach discussed yonder. It also feels 'cleaner', as there is just a single place where default labels are determined and we have no need to moonlight in ggplot_add() methods (notable exception is ggplot_add.labels() for obvious reason that these are user specified non-default labels). The drawback is that we desecrate ggplot_build().

Let's demonstrate using plots that are limitations in the other PR. Labels are not baked in at construction time, so %+% data replacement works as intended.

devtools::load_all("~/packages/ggplot2")
#> ℹ Loading ggplot2

df <- mtcars
attr(df$mpg,  "label") <- "Miles per gallon"
attr(df$disp, "label") <- "Displacement"
attr(df$drat, "label") <- "Rear axle ratio"

p <- ggplot(mtcars, aes(mpg, .data$disp)) +
  geom_point(aes(colour = drat))
p %+% df

Naively, it doesn't appear to work when data is not a data.frame.

ggplot(df, aes(mpg, .data$disp)) +
  geom_point(aes(colour = drat), data = ~ subset(.x, mpg > 20))

However, this is just because subset() drops attributes. If we use dplyr::filter() that doesn't drop attributes, it works just fine.

ggplot(df, aes(mpg, .data$disp)) +
  geom_point(aes(colour = drat), data = ~ dplyr::filter(.x, mpg > 20))

Created on 2024-05-02 with reprex v2.1.0

The choice is thus:

teunbrand commented 1 month ago

This PR had an unexpected interaction with get_alt_text() when the alt-text was a function (introduced in #5079). The problem was that alt-text functions could no longer read out plot labels before the plot is build, so the solution here is to apply get_alt_text()-functions to build plots.