1

I noticed a strange behavior with ggplot. I want to create multiple figures one after another, while reassigning data variables in between. The problem is that ggplot uses the new value for the previously saved graphs.

Here is a simple example of the behavior, but keep in mind that this is part of a larger workflow, where I create multiple plots and join them at the end with grid.arrange.

resp <- iris$Sepal.Length
p <- ggplot(iris, aes(x = Petal.Length, y = resp))+
    geom_point()
p

This is the normal plot:

normal plot

Now I reassign resp, but I would expect p not to change. However, it does!

resp <- iris$Sepal.Width
p

THis is the changed plot:

changed plot

As you can see, p now uses iris$Sepal.Width for y, which is not the desired behavior. Why is that, and how can I make this work the way I want?

Interestingly, it works fine when the plotting is in a function. Still, I would like a solution without this workaround.

irisplot <- function(resp){
  panel <- ggplot(iris, aes(Petal.Length, resp))+
    geom_point()
  return(panel)
}

q1 <- irisplot(iris$Sepal.Length)
q2 <- irisplot(iris$Sepal.Width)

q1 #as expected

Also, I read that it might be bad practice to use vectors in aes() (e.g. this and this), so I am also open to solutions that address that.

aboger
  • 2,214
  • 6
  • 33
  • 47
Goine0
  • 83
  • 1
  • 6

1 Answers1

1

ggplot2 saves the data.frame passed to the data parameter in the ggplot object. For anything referenced in aes that is not in this data.frame it has to rely on scoping to find it when the plot is build (each time it is printed).

So, just make sure that resp is passed to the data parameter, too.

resp <- iris$Sepal.Length
p <- ggplot(cbind(iris, resp), aes(x = Petal.Length, y = resp))+
  geom_point()
p

resp <- iris$Sepal.Width
p
#same plot

PS: Your example with the function works, because the plot environment of q1 and q2 are environments created during the function call whereas the plot environment of p is the global environment. Compare p$plot_env and q1$plot_env and check out ls(q1$plot_env).

Roland
  • 127,288
  • 10
  • 191
  • 288