2

I've been trying to draw two plots using R's ggplot library in RStudio. Problem is, when I draw two within one function, only the last one displays (in RStudio's "plots" view) and the first one disappears. Even worse, when I run ggsave() after each plot - which saves them to a file - neither of them appear (but the files save as expected). However, I want to view what I've saved in the plots as I was able to before.

Is there a way I can both display what I'll be plotting in RStudio's plots view and also save them? Moreover, when the plots are not being saved, why does the display problem happen when there's more than one plot? (i.e. why does it show the last one but not the ones before?)

The code with the plotting parts are below. I've removed some parts because they seem unnecessary (but can add them if they are indeed relevant).

HHIplot = ggplot(pergame)
# some ggplot geoms and misc. here  
ggsave(paste("HHI Index of all games,",year,"Finals.png"), 
  path = plotpath, width = 6, height = 4)

HHIAvePlot = ggplot(AveHHI, aes(x = AveHHI$n_brokers))
# some ggplot geoms and misc. here
ggsave(paste("Average HHI Index of all games,",year,"Finals.png"), 
  path = plotpath, width = 6, height = 4)

I've already taken a look here and here but neither have helped. Adding a print(HHIplot) or print(HHIAvePlot) after the ggsave() lines has not displayed the plot.

Many thanks in advance.


Update 1: The solution suggested below didn't work, although it works for the answer's sample code. I passed the ggplot objects to .Globalenv and print() gives me an empty gray box on the plot area (which I imagine is an empty ggplot object with no layers). I think the issue might lie in some of the layers or manipulators I have used, so I've brought the full code for one ggplot object below. Any thoughts? (Note: I've tried putting the assign() line in all possible locations in relation to ggsave() and ggplot().)

HHIplot = ggplot(pergame)
HHIplot +
  geom_point(aes(x = pergame$n_brokers, y = pergame$HHI)) +
  scale_y_continuous(limits = c(0,10000)) +
  scale_x_discrete(breaks = gameSizes) +
  labs(title = paste("HHI Index of all games,",year,"Finals"),
      x = "Game Size", y = "Herfindahl-Hirschman Index") +
  theme(text = element_text(size=15),axis.text.x = element_text(angle = 0, hjust = 1))
assign("HHIplot",HHIplot, envir = .GlobalEnv)
ggsave(paste("HHI Index of all games,",year,"Finals.png"),
  path = plotpath, width = 6, height = 4)
Community
  • 1
  • 1
  • 3
    The RStudio plot graphics pane has two left/right arrows in the upper left that can be used to move back and forth in the history of plots printed to the current device. – joran Dec 29 '15 at 20:57
  • Joran, indeed it does, and the first plot does not show up when I do this to view it. I use those arrows often. – Mohammad Ansarin Dec 30 '15 at 07:06

1 Answers1

2

I'll preface this by saying that the following is bad practice. It's considered bad practice to break a programming language's scoping rules for something as trivial as this, but here's how it's done anyway.

So within the body of your function you'll create both plots and put them into variables. Then you'll use ggsave() to write them out. Finally, you'll use assign() to push the variables to the global scope.

library(ggplot2)
myFun <- function() {
    #some sample data that you should be passing into the function via arguments
    df <- data.frame(x=1:10, y1=1:10, y2=10:1)
    p1 <- ggplot(df, aes(x=x, y=y1))+geom_point()
    p2 <- ggplot(df, aes(x=x, y=y2))+geom_point()
    ggsave('p1.jpg', p1)
    ggsave('p2.jpg', p2)
    assign('p1', p1, envir=.GlobalEnv)
    assign('p2', p2, envir=.GlobalEnv)
    return()
}

Now, when you run myFun() it will write out your two plots to .jpg files, and also drop the plots into your global environment so that you can just run p1 or p2 on the console and they'll appear in RStudio's Plot pane.

ONCE AGAIN, THIS IS BAD PRACTICE

Good practice would be to not worry about the fact that they're not popping up in RStudio. They wrote out to files, and you know they did, so go look at them there.

doicomehereoften1
  • 537
  • 1
  • 4
  • 12
  • Doicomehereoften, many thanks for the help. Would it be too much to ask what you mean by "a programming language's scoping rules" and why it's considered bad practice to break it? I use `assign()` sometimes to put variables in the global environment. – Mohammad Ansarin Dec 30 '15 at 07:05
  • Update: it didn't work. Although your code runs fine (`print(p1)` and `print(p2)` show the plots as expected), sending my ggplots to .Globalenv and running `print()` on them doesn't show the plots. I only get an empty gray screen (I imagine a ggplot object with no layers is passed on). I'll add some more of the code in the main question. – Mohammad Ansarin Dec 30 '15 at 07:41
  • Don't use `print()`. Just run `p1` or `p2`. There's a lot written elsewhere about scoping, so just start looking stuff up, the Wikipedia page on scoping is a good place to start. It's bad practice because the function itself doesn't `return` anything. A function ought to return something such as a file or a value to be put into a variable. The function I wrote above returns nothing, writes out two files, and has two side-effects that wouldn't be expected from a naive running of the function. – doicomehereoften1 Dec 30 '15 at 16:34
  • I have tried running just `p1` and `p2`, it basically gives the same result as using `print()`. – Mohammad Ansarin Dec 30 '15 at 20:16
  • The reason it doesn't work is in your updated code. You don't add your geoms, scales, etc into your actual plot variable. To dovetail with the discussion of good/bad practice, this is indicative of good practice, since none of the functions you're `+`ing onto `HHIplot` are sticking without actually assigning to a variable. In other words: They don't have side effects on your environment by just running them. – doicomehereoften1 Dec 30 '15 at 23:45