|
2 | 2 | #'
|
3 | 3 | #' Most aesthetics are mapped from variables found in the data. Sometimes,
|
4 | 4 | #' however, you want to delay the mapping until later in the rendering process.
|
5 |
| -#' ggplot2 has three stages of the data that you can map aesthetics from. The |
6 |
| -#' default is to map at the beginning, using the layer data provided by the |
7 |
| -#' user. The second stage is after the data has been transformed by the layer |
8 |
| -#' stat. The third and last stage is after the data has been transformed and |
9 |
| -#' mapped by the plot scales. The most common example of mapping from stat |
10 |
| -#' transformed data is the height of bars in [geom_histogram()]: |
11 |
| -#' the height does not come from a variable in the underlying data, but |
12 |
| -#' is instead mapped to the `count` computed by [stat_bin()]. An example of |
13 |
| -#' mapping from scaled data could be to use a desaturated version of the stroke |
14 |
| -#' colour for fill. If you want to map directly from the layer data you should |
15 |
| -#' not do anything special. In order to map from stat transformed data you |
16 |
| -#' should use the `after_stat()` function to flag that evaluation of the |
17 |
| -#' aesthetic mapping should be postponed until after stat transformation. |
18 |
| -#' Similarly, you should use `after_scale()` to flag evaluation of mapping for |
19 |
| -#' after data has been scaled. If you want to map the same aesthetic multiple |
20 |
| -#' times, e.g. map `x` to a data column for the stat, but remap it for the geom, |
21 |
| -#' you can use the `stage()` function to collect multiple mappings. |
| 5 | +#' ggplot2 has three stages of the data that you can map aesthetics from, and |
| 6 | +#' three functions to control at which stage aesthetics should be evaluated. |
22 | 7 | #'
|
| 8 | +#' @usage # These functions can be used inside the `aes()` function |
| 9 | +#' # used as the `mapping` argument in layers. |
| 10 | +#' |
| 11 | +#' @param x <[`data-masking`][rlang::topic-data-mask]> An aesthetic expression |
| 12 | +#' using variables calculated by the stat (`after_stat()`) or layer aesthetics |
| 13 | +#' (`after_scale()`). |
| 14 | +#' @param start <[`data-masking`][rlang::topic-data-mask]> An aesthetic |
| 15 | +#' expression using variables from the layer data. |
| 16 | +#' @param after_stat <[`data-masking`][rlang::topic-data-mask]> An aesthetic |
| 17 | +#' expression using variables calculated by the stat. |
| 18 | +#' @param after_scale <[`data-masking`][rlang::topic-data-mask]> An aesthetic |
| 19 | +#' expression using layer aesthetics. |
| 20 | +#' |
| 21 | +#' @note |
23 | 22 | #' `after_stat()` replaces the old approaches of using either `stat()` or
|
24 | 23 | #' surrounding the variable names with `..`.
|
25 | 24 | #'
|
26 |
| -#' @note Evaluation after stat transformation will have access to the |
27 |
| -#' variables calculated by the stat, not the original mapped values. Evaluation |
28 |
| -#' after scaling will only have access to the final aesthetics of the layer |
29 |
| -#' (including non-mapped, default aesthetics). The original layer data can only |
30 |
| -#' be accessed at the first stage. |
| 25 | +#' @section Staging: |
| 26 | +#' Below follows an overview of the three stages of evaluation and how aesthetic |
| 27 | +#' evaluation can be controlled. |
| 28 | +#' |
| 29 | +#' ## Stage 1: direct input |
| 30 | +#' The default is to map at the beginning, using the layer data provided by |
| 31 | +#' the user. If you want to map directly from the layer data you should not do |
| 32 | +#' anything special. This is the only stage where the original layer data can |
| 33 | +#' be accessed. |
| 34 | +#' |
| 35 | +#' ```{r direct_input, eval = FALSE} |
| 36 | +#' # 'x' and 'y' are mapped directly |
| 37 | +#' ggplot(mtcars) + geom_point(aes(x = mpg, y = disp)) |
| 38 | +#' ``` |
| 39 | +#' |
| 40 | +#' ## Stage 2: after stat transformation |
| 41 | +#' The second stage is after the data has been transformed by the layer |
| 42 | +#' stat. The most common example of mapping from stat transformed data is the |
| 43 | +#' height of bars in [geom_histogram()]: the height does not come from a |
| 44 | +#' variable in the underlying data, but is instead mapped to the `count` |
| 45 | +#' computed by [stat_bin()]. In order to map from stat transformed data you |
| 46 | +#' should use the `after_stat()` function to flag that evaluation of the |
| 47 | +#' aesthetic mapping should be postponed until after stat transformation. |
| 48 | +#' Evaluation after stat transformation will have access to the variables |
| 49 | +#' calculated by the stat, not the original mapped values. The 'computed |
| 50 | +#' variables' section in each stat lists which variables are available to |
| 51 | +#' access. |
| 52 | +#' |
| 53 | +#' ```{r after_stat_transformation, eval = FALSE} |
| 54 | +#' # The 'y' values for the histogram are computed by the stat |
| 55 | +#' ggplot(faithful, aes(x = waiting)) + |
| 56 | +#' geom_histogram() |
| 57 | +#' |
| 58 | +#' # Choosing a different computed variable to display, matching up the |
| 59 | +#' # histogram with the density plot |
| 60 | +#' ggplot(faithful, aes(x = waiting)) + |
| 61 | +#' geom_histogram(aes(y = after_stat(density))) + |
| 62 | +#' geom_density() |
| 63 | +#' ``` |
| 64 | +#' |
| 65 | +#' ## Stage 3: after scale transformation |
| 66 | +#' The third and last stage is after the data has been transformed and |
| 67 | +#' mapped by the plot scales. An example of mapping from scaled data could |
| 68 | +#' be to use a desaturated version of the stroke colour for fill. You should |
| 69 | +#' use `after_scale()` to flag evaluation of mapping for after data has been |
| 70 | +#' scaled. Evaluation after scaling will only have access to the final |
| 71 | +#' aesthetics of the layer (including non-mapped, default aesthetics). |
| 72 | +#' |
| 73 | +#' ```{r after_scale_transformation, eval = FALSE} |
| 74 | +#' # The exact colour is known after scale transformation |
| 75 | +#' ggplot(mpg, aes(cty, colour = factor(cyl))) + |
| 76 | +#' geom_density() |
| 77 | +#' |
| 78 | +#' # We re-use colour properties for the fill without a separate fill scale |
| 79 | +#' ggplot(mpg, aes(cty, colour = factor(cyl))) + |
| 80 | +#' geom_density(aes(fill = after_scale(alpha(colour, 0.3)))) |
| 81 | +#' ``` |
31 | 82 | #'
|
32 |
| -#' @param x An aesthetic expression using variables calculated by the stat |
33 |
| -#' (`after_stat()`) or layer aesthetics (`after_scale()`). |
34 |
| -#' @param start An aesthetic expression using variables from the layer data. |
35 |
| -#' @param after_stat An aesthetic expression using variables calculated by the |
36 |
| -#' stat. |
37 |
| -#' @param after_scale An aesthetic expression using layer aesthetics. |
| 83 | +#' ## Complex staging |
| 84 | +#' If you want to map the same aesthetic multiple times, e.g. map `x` to a |
| 85 | +#' data column for the stat, but remap it for the geom, you can use the |
| 86 | +#' `stage()` function to collect multiple mappings. |
| 87 | +#' |
| 88 | +#' ```{r complex_staging, eval = FALSE} |
| 89 | +#' # Use stage to modify the scaled fill |
| 90 | +#' ggplot(mpg, aes(class, hwy)) + |
| 91 | +#' geom_boxplot(aes(fill = stage(class, after_scale = alpha(fill, 0.4)))) |
| 92 | +#' |
| 93 | +#' # Using data for computing summary, but placing label elsewhere, as well as |
| 94 | +#' # using the computed 'y' as part of the label. |
| 95 | +#' ggplot(mpg, aes(class, displ)) + |
| 96 | +#' geom_violin() + |
| 97 | +#' stat_summary( |
| 98 | +#' aes(y = stage(displ, after_stat = 8), |
| 99 | +#' label = after_stat(paste(y, ymax, sep = " ± "))), |
| 100 | +#' geom = "text", |
| 101 | +#' fun = ~ round(mean(.x), 2), |
| 102 | +#' fun.max = ~ round(sd(.x), 2) |
| 103 | +#' ) |
| 104 | +#' ``` |
38 | 105 | #'
|
39 | 106 | #' @rdname aes_eval
|
40 | 107 | #' @name aes_eval
|
|
55 | 122 | #' # Use stage to modify the scaled fill
|
56 | 123 | #' ggplot(mpg, aes(class, hwy)) +
|
57 | 124 | #' geom_boxplot(aes(fill = stage(class, after_scale = alpha(fill, 0.4))))
|
| 125 | +#' |
| 126 | +#' # Making a proportional stacked density plot |
| 127 | +#' ggplot(mpg, aes(cty)) + |
| 128 | +#' geom_density( |
| 129 | +#' aes(colour = factor(cyl), |
| 130 | +#' fill = after_scale(alpha(colour, 0.3)), |
| 131 | +#' y = after_stat(count / sum(n[!duplicated(group)]))), |
| 132 | +#' position = "stack", bw = 1 |
| 133 | +#' ) + |
| 134 | +#' geom_density(bw = 1) |
| 135 | +#' |
| 136 | +#' # Imitating a ridgeline plot |
| 137 | +#' ggplot(mpg, aes(cty, colour = factor(cyl))) + |
| 138 | +#' geom_ribbon( |
| 139 | +#' stat = "density", outline.type = "upper", |
| 140 | +#' aes(fill = after_scale(alpha(colour, 0.3)), |
| 141 | +#' ymin = after_stat(group), |
| 142 | +#' ymax = after_stat(group + ndensity)) |
| 143 | +#' ) |
| 144 | +#' |
| 145 | +#' # Labelling a bar plot |
| 146 | +#' ggplot(mpg, aes(class)) + |
| 147 | +#' geom_bar() + |
| 148 | +#' geom_text( |
| 149 | +#' aes(y = after_stat(count + 2), |
| 150 | +#' label = after_stat(count)), |
| 151 | +#' stat = "count" |
| 152 | +#' ) |
| 153 | +#' |
| 154 | +#' # Labelling the upper hinge of a boxplot, |
| 155 | +#' # inspired by June Choe |
| 156 | +#' ggplot(mpg, aes(displ, class)) + |
| 157 | +#' geom_boxplot(outlier.shape = NA) + |
| 158 | +#' geom_text( |
| 159 | +#' aes(label = after_stat(xmax), |
| 160 | +#' x = stage(displ, after_stat = xmax)), |
| 161 | +#' stat = "boxplot", hjust = -0.5 |
| 162 | +#' ) |
58 | 163 | NULL
|
59 | 164 |
|
60 | 165 | #' @rdname aes_eval
|
|
0 commit comments