I'm wandering if it's possible to get the mapping between factor levels and fill colors of bars. For example:
library(ggplot2)
library(dplyr)
d <- mtcars %>% mutate_at(vars(am, cyl, carb, gear, vs), as.factor) # make factors from vars
p <- ggplot(
data = d,
aes(x = am, fill = cyl)
) geom_bar()
Now, I examine the underlying data in an object built from the plot
built <- ggplot2::ggplot_build(p)
and I can see something like this:
> built$data[[1]]
fill y count prop x flipped_aes PANEL group ymin ymax xmin xmax colour size linetype alpha
1 #F8766D 19 3 1 1 FALSE 1 1 16 19 0.55 1.45 NA 0.5 1 NA
2 #00BA38 16 4 1 1 FALSE 1 2 12 16 0.55 1.45 NA 0.5 1 NA
3 #619CFF 12 12 1 1 FALSE 1 3 0 12 0.55 1.45 NA 0.5 1 NA
4 #F8766D 13 8 1 2 FALSE 1 4 5 13 1.55 2.45 NA 0.5 1 NA
5 #00BA38 5 3 1 2 FALSE 1 5 2 5 1.55 2.45 NA 0.5 1 NA
6 #619CFF 2 2 1 2 FALSE 1 6 0 2 1.55 2.45 NA 0.5 1 NA
My question is, how can I get explicit information which factor level mapped to the fill
aesthetic corresponds to which fill value in the above dataset? My example is very simple, but the real use-case is that all I have as the input is only a plot of class ggplot.
CodePudding user response:
library(tidyverse)
d <- mtcars %>% mutate_at(vars(am, cyl, carb, gear, vs), as.factor) # make factors from vars
p <- ggplot(
data = d,
aes(x = am, fill = cyl)
) geom_bar()
q <- ggplot_build(p)
# mappings
q[["plot"]][["mapping"]]
#> Aesthetic mapping:
#> * `x` -> `am`
#> * `fill` -> `cyl`
# fill levels
q[["plot"]][["scales"]][["scales"]][[2]][["palette.cache"]]
#> [1] "#F8766D" "#00BA38" "#619CFF"
# mapped aesthetic levels
q[["plot"]][["scales"]][["scales"]][[2]][["range"]][["range"]]
#> [1] "4" "6" "8"
Created on 2021-12-14 by the reprex package (v2.0.1)