-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathaes_eval.Rd
212 lines (179 loc) · 7.28 KB
/
aes_eval.Rd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/aes-evaluation.R
\name{aes_eval}
\alias{aes_eval}
\alias{after_stat}
\alias{stat}
\alias{after_scale}
\alias{from_theme}
\alias{stage}
\title{Control aesthetic evaluation}
\usage{
# These functions can be used inside the `aes()` function
# used as the `mapping` argument in layers, for example:
# geom_density(mapping = aes(y = after_stat(scaled)))
after_stat(x)
after_scale(x)
from_theme(x)
stage(start = NULL, after_stat = NULL, after_scale = NULL)
}
\arguments{
\item{x}{<\code{\link[rlang:topic-data-mask]{data-masking}}> An aesthetic expression
using variables calculated by the stat (\code{after_stat()}) or layer aesthetics
(\code{after_scale()}).}
\item{start}{<\code{\link[rlang:topic-data-mask]{data-masking}}> An aesthetic
expression using variables from the layer data.}
\item{after_stat}{<\code{\link[rlang:topic-data-mask]{data-masking}}> An aesthetic
expression using variables calculated by the stat.}
\item{after_scale}{<\code{\link[rlang:topic-data-mask]{data-masking}}> An aesthetic
expression using layer aesthetics.}
}
\description{
Most \link[=aes]{aesthetics} are mapped from variables found in the data.
Sometimes, however, you want to delay the mapping until later in the
rendering process. ggplot2 has three stages of the data that you can map
aesthetics from, and three functions to control at which stage aesthetics
should be evaluated.
\code{after_stat()} replaces the old approaches of using either \code{stat()}, e.g.
\code{stat(density)}, or surrounding the variable names with \code{..}, e.g.
\code{..density..}.
}
\section{Staging}{
Below follows an overview of the three stages of evaluation and how aesthetic
evaluation can be controlled.
\subsection{Stage 1: direct input at the start}{
The default is to map at the beginning, using the layer data provided by
the user. If you want to map directly from the layer data you should not do
anything special. This is the only stage where the original layer data can
be accessed.
\if{html}{\out{<div class="sourceCode r">}}\preformatted{# 'x' and 'y' are mapped directly
ggplot(mtcars) + geom_point(aes(x = mpg, y = disp))
}\if{html}{\out{</div>}}
}
\subsection{Stage 2: after stat transformation}{
The second stage is after the data has been transformed by the layer
stat. The most common example of mapping from stat transformed data is the
height of bars in \code{\link[=geom_histogram]{geom_histogram()}}: the height does not come from a
variable in the underlying data, but is instead mapped to the \code{count}
computed by \code{\link[=stat_bin]{stat_bin()}}. In order to map from stat transformed data you
should use the \code{after_stat()} function to flag that evaluation of the
aesthetic mapping should be postponed until after stat transformation.
Evaluation after stat transformation will have access to the variables
calculated by the stat, not the original mapped values. The 'computed
variables' section in each stat lists which variables are available to
access.
\if{html}{\out{<div class="sourceCode r">}}\preformatted{# The 'y' values for the histogram are computed by the stat
ggplot(faithful, aes(x = waiting)) +
geom_histogram()
# Choosing a different computed variable to display, matching up the
# histogram with the density plot
ggplot(faithful, aes(x = waiting)) +
geom_histogram(aes(y = after_stat(density))) +
geom_density()
}\if{html}{\out{</div>}}
}
\subsection{Stage 3: after scale transformation}{
The third and last stage is after the data has been transformed and
mapped by the plot scales. An example of mapping from scaled data could
be to use a desaturated version of the stroke colour for fill. You should
use \code{after_scale()} to flag evaluation of mapping for after data has been
scaled. Evaluation after scaling will only have access to the final
aesthetics of the layer (including non-mapped, default aesthetics).
\if{html}{\out{<div class="sourceCode r">}}\preformatted{# The exact colour is known after scale transformation
ggplot(mpg, aes(cty, colour = factor(cyl))) +
geom_density()
# We re-use colour properties for the fill without a separate fill scale
ggplot(mpg, aes(cty, colour = factor(cyl))) +
geom_density(aes(fill = after_scale(alpha(colour, 0.3))))
}\if{html}{\out{</div>}}
}
\subsection{Complex staging}{
Sometimes, you may want to map the same aesthetic multiple times, e.g. map
\code{x} to a data column at the start for the layer stat, but remap it later to
a variable from the stat transformation for the layer geom. The \code{stage()}
function allows you to control multiple mappings for the same aesthetic
across all three stages of evaluation.
\if{html}{\out{<div class="sourceCode r">}}\preformatted{# Use stage to modify the scaled fill
ggplot(mpg, aes(class, hwy)) +
geom_boxplot(aes(fill = stage(class, after_scale = alpha(fill, 0.4))))
# Using data for computing summary, but placing label elsewhere.
# Also, we're making our own computed variables to use for the label.
ggplot(mpg, aes(class, displ)) +
geom_violin() +
stat_summary(
aes(
y = stage(displ, after_stat = 8),
label = after_stat(paste(mean, "±", sd))
),
geom = "text",
fun.data = ~ round(data.frame(mean = mean(.x), sd = sd(.x)), 2)
)
}\if{html}{\out{</div>}}
Conceptually, \code{aes(x)} is equivalent to \code{aes(stage(start = x))}, and
\code{aes(after_stat(count))} is equivalent to \code{aes(stage(after_stat = count))},
and so on. \code{stage()} is most useful when at least two of its arguments are
specified.
}
\subsection{Theme access}{
The \code{from_theme()} function can be used to acces the \code{\link[=element_geom]{element_geom()}}
fields of the \code{theme(geom)} argument. Using \code{aes(colour = from_theme(ink))}
and \code{aes(colour = from_theme(accent))} allows swapping between foreground and
accent colours.
}
}
\examples{
# Default histogram display
ggplot(mpg, aes(displ)) +
geom_histogram(aes(y = after_stat(count)))
# Scale tallest bin to 1
ggplot(mpg, aes(displ)) +
geom_histogram(aes(y = after_stat(count / max(count))))
# Use a transparent version of colour for fill
ggplot(mpg, aes(class, hwy)) +
geom_boxplot(aes(colour = class, fill = after_scale(alpha(colour, 0.4))))
# Use stage to modify the scaled fill
ggplot(mpg, aes(class, hwy)) +
geom_boxplot(aes(fill = stage(class, after_scale = alpha(fill, 0.4))))
# Making a proportional stacked density plot
ggplot(mpg, aes(cty)) +
geom_density(
aes(
colour = factor(cyl),
fill = after_scale(alpha(colour, 0.3)),
y = after_stat(count / sum(n[!duplicated(group)]))
),
position = "stack", bw = 1
) +
geom_density(bw = 1)
# Imitating a ridgeline plot
ggplot(mpg, aes(cty, colour = factor(cyl))) +
geom_ribbon(
stat = "density", outline.type = "upper",
aes(
fill = after_scale(alpha(colour, 0.3)),
ymin = after_stat(group),
ymax = after_stat(group + ndensity)
)
)
# Labelling a bar plot
ggplot(mpg, aes(class)) +
geom_bar() +
geom_text(
aes(
y = after_stat(count + 2),
label = after_stat(count)
),
stat = "count"
)
# Labelling the upper hinge of a boxplot,
# inspired by June Choe
ggplot(mpg, aes(displ, class)) +
geom_boxplot(outlier.shape = NA) +
geom_text(
aes(
label = after_stat(xmax),
x = stage(displ, after_stat = xmax)
),
stat = "boxplot", hjust = -0.5
)
}