By assigning a ggplot() object to a variable, one can easily reuse the object and make multiple versions of a plot with variations on the geom layers without redundant code for each plot. However, I was wondering if there's a way to reuse geom layers while swapping the global aesthetic mappings.
One use case for this is that I want to make several plots with the same geometric representations, but want to swap out the variable mapped to one of the dimensions. Another use case is that I want to make two plots where the data come from two different data frames.
The intuitive way to go about this would be to 1) save the combination of the geom layers to a variable without assigning a ggplot() object or 2) override the data and aesthetics of an existing ggplot() object in a variable by adding another ggplot() object. Doing either of these things causes errors though (for 1- "non-numeric argument to binary operator, for 2 - "Don't know how to add o to a plot").
For example, suppose in the following plot I want to re-use the gg variable but remap the x variable to something else in the dataframe:
dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
gg <-
(ggplot(data = dsamp, aes(x = carat, y = price, color = clarity))
+ geom_point()
+ facet_wrap(~ cut))
print(gg)
In practice plot definitions can be a lot more than 3 lines long, which is why this starts to be a code maintenance annoyance.
Aesthetic mappings describe how variables in the data are mapped to visual properties (aesthetics) of geoms. Aesthetic mappings can be set in ggplot() and in individual layers.
Basics. Note that, aes() is passed to either ggplot() or to specific layer. Aesthetics specified to ggplot() are used as defaults for every layer.
Aesthetic Mapping ( aes ) In ggplot2 , aesthetic means “something you can see”. Each aesthetic is a mapping between a visual cue and a variable. Examples include: position (i.e., on the x and y axes) color (“outside” color)
Each geom function in ggplot2 takes a mapping argument. This defines how variables in your dataset are mapped to visual properties. The mapping argument is always paired with aes() , and the x and y arguments of aes() specify which variables to map to the x- and y-axes.
Swapping variables associated with aesthetics and the data associated with a plot are both straightforward. Using the gg
you define in the question, use aes
by itself to change aesthetics:
gg + aes(x=table, y=depth)
To change the data used for a plot, use the %+%
operator.
dsamp2 <- head(diamonds, 100)
gg %+% dsamp2
Like joran mentioned, I'm guessing... but:
you can do one of two things, edit the ggplot2 object (bad idea) or wrap the plot in a function.
lets use the following data and plot call:
dat <- data.frame(x=1:10, y=10:1, z=1, a=letters[1:2], b=letters[3:4])
# p <- ggplot(dat, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()
Notice I used aes_string
so I can pass variables rather than names of columns.
xvar <- 'y'
yvar <- 'z'
colorvar <- 'a'
p <- ggplot(dat, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()
The structure of p
is below and I'll leave it to you to sort out editing it. Instead, wrap the ggplot in a function:
plotfun <- function(DF, xvar, yvar, colorvar) {
ggplot(DF, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()
}
p <- plotfun(dat, 'z', 'x', 'a')
p
str(p)
List of 8
$ data :'data.frame': 10 obs. of 5 variables:
..$ x: int [1:10] 1 2 3 4 5 6 7 8 9 10
..$ y: int [1:10] 10 9 8 7 6 5 4 3 2 1
..$ z: num [1:10] 1 1 1 1 1 1 1 1 1 1
..$ a: chr [1:10] "a" "b" "a" "b" ...
..$ b: chr [1:10] "c" "d" "c" "d" ...
$ layers :List of 1
..$ :Classes 'proto', 'environment' <environment: 0x34d5628>
$ scales :Reference class 'Scales' [package "ggplot2"] with 1 fields
..$ scales: list()
..and 20 methods, of which 9 are possibly relevant:
.. add, clone, find, get_scales, has_scale, initialize, input, n, non_position_scales
$ mapping :List of 3
..$ x : symbol y
..$ y : symbol x
..$ colour: symbol a
$ options :List of 1
..$ labels:List of 3
.. ..$ x : chr "z"
.. ..$ y : chr "x"
.. ..$ colour: chr "a"
$ coordinates:List of 1
..$ limits:List of 2
.. ..$ x: NULL
.. ..$ y: NULL
..- attr(*, "class")= chr [1:2] "cartesian" "coord"
$ facet :List of 1
..$ shrink: logi TRUE
..- attr(*, "class")= chr [1:2] "null" "facet"
$ plot_env :<environment: R_GlobalEnv>
- attr(*, "class")= chr "ggplot"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With