rggplot2aesthetics

How do I pass aesthetics to stat_summary in ggplot2?


I'm trying to produce the following plot (working example from mtcars)

enter image description here

I can obviously do it by summarizing my data beforehand, but I would like to do it on the fly using something like this:

mtcars %>%
  ggplot(aes(x = cyl, y = hp, label = round(hp))) +
    stat_summary(fun = mean, geom = "point") +
    stat_summary(fun = mean, geom = "text")

Or this:

mtcars %>%
  ggplot(aes(x = cyl, y = hp, label = round(hp))) +
    geom_point(stat = "summary", fun = mean) +
    geom_text(stat = "summary", fun = mean)

However I get the following error message:

Error in stat_summary(): ! Problem while setting up geom. ℹ Error occurred in the 2nd layer. Caused by error in compute_geom_1(): ! geom_text() requires the following missing aesthetics: label

I'm not sure why geom_text is not receiving the label aesthetic I've provided in the original ggplot2 call - afterall the y aesthetic seems to be passed along just fine to geom_point. Providing the label aesthetic in the geom_text line does not avoid the error.


Solution

  • When using stat_summary you have to use after_stat to map the computed mean value on the label aes, where in case of stat_summary the computed value is stored in a column named y.

    Note: I switched to geom="label" (with fill=NA and label.size=0 to add some padding between the point and the label.

    library(ggplot2)
    
    mtcars |> 
      ggplot(aes(x = cyl, y = hp, label = round(hp))) +
      stat_summary(
        fun = mean, geom = "point", 
        shape = 21, fill = "white", size = 3) +
      stat_summary(
        aes(label = after_stat(round(y))),
        fun = mean, geom = "label",
        hjust = 0, fill = NA, label.size = 0,
        label.padding = unit(3, "mm")
      ) +
      coord_cartesian(clip = "off")