Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 - is there a way to override global aesthetic mappings while reusing geom layers

Tags:

r

ggplot2

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.

like image 421
daj Avatar asked Aug 17 '12 19:08

daj


People also ask

What does it mean to set the aesthetic mappings in ggplot?

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.

What function is used to pass aesthetic information into a ggplot graph?

Basics. Note that, aes() is passed to either ggplot() or to specific layer. Aesthetics specified to ggplot() are used as defaults for every layer.

What does AES stand for in ggplot?

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)

What is the mapping argument in R?

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.


2 Answers

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 image 165
Brian Diggs Avatar answered Oct 19 '22 10:10

Brian Diggs


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"
like image 32
Justin Avatar answered Oct 19 '22 09:10

Justin