0

I am making ggplots using for loop function and wanted to save all the plots in a file for using in ppt format.

The code I am using is

for(i in 1:28) {
  plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
          ggtitle(names(Num)[i])+theme_classic()

  ggplot2::ggsave(filename = paste0("plot_",i,".png"),plot_i, path = "E:/Folder1")

}

However when i open the saved png file only 1 out of all 28 graphs is visible When i check if the graphs are actually made or not all the graphs are being made in r studio

for(i in 1:28) {
  print(ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
          ggtitle(names(Num)[i]))+theme_classic()
}

This codes helps me in viewing all the plots, but if i have to save it i have to go one by one which is very lengthy process. it will be useful for me if i could save the plots in .doc or .ppt file I have checked similar questions here but the solutions given are not working.

  • Try using `dev.off()` as the last command within the loop. It closes the active graph and then does the entire process for the next graph. – kashj Jul 25 '20 at 07:16
  • 1
    dev.off shouldn’t be needed with ggsave. Are you sure that’s it @kashj – MrFlick Jul 25 '20 at 07:18
  • @kashj....i have tried..but same result...only 1 graph coming i the png file, all others are missing – Sourabh_me Jul 25 '20 at 07:21
  • @MrFlick.....yes you got it right. I want each plots in png format in individual file but i am getting only one file i.e plot_24. and it has only one graph – Sourabh_me Jul 25 '20 at 07:25
  • insert `print(plot_i)` command before `ggsave` command? – monte Jul 25 '20 at 07:29
  • @MrFlick, thanks for that. I was not sure. – kashj Jul 25 '20 at 07:30
  • @monte... it worked....i got all the 28 graphs as png file in the folder....Thanks – Sourabh_me Jul 25 '20 at 07:33
  • @monte do you know when that’s needed when the plot is being passed explicitly to ggsave as a parameter? It seems like that should take care of the print(). – MrFlick Jul 25 '20 at 07:36
  • @MrFlick i have added the answer, with more detailed explanation – monte Jul 25 '20 at 18:32

3 Answers3

2

In the code you had shared:

for(i in 1:28) {
  plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
          ggtitle(names(Num)[i])+theme_classic()

  ggplot2::ggsave(filename = paste0("plot_",i,".png"),plot_i, path = "E:/Folder1")

}

You are storing the plot object in the variable plot_i. You are not printing those plots. You need to insert, print(plot_i) statement before saving the plot using ggplot as follows:

for(i in 1:28) {
  plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
          ggtitle(names(Num)[i])+theme_classic()

  print(plot_i)

  ggplot2::ggsave(filename = paste0("plot_",i,".png"),plot_i, path = "E:/Folder1")

}

The reason why you need to print is because, ggsave defaults to save the last displayed plot, and by printing you actually display on the Rs display devices. In simpler words this is what ggsave does:

png('file_name.png') #it opens a graphics devices, can be other also like jpeg
print(plot_i) #displays the plot on graphics device
dev.off() #closes the graphic device
monte
  • 1,482
  • 1
  • 10
  • 26
  • This still doesn't make sense. You only need the `print()` if you aren't passing the plot directly to `ggsave()`. This works perfectly fine for me: `for(i in 1:3) {p <- ggplot(mtcars, aes(mtcars[,i])) + geom_histogram(); ggsave(paste("plot", i, ".png"), p)}` Does it not for you? I think the OP must be leaving something out. – MrFlick Jul 25 '20 at 18:39
1

Try this once. It does not involve ggplot2 though.

for(i in 1:28){
   jpeg(filename= paste("E:/Folder1/plot_",i,".png", sep= "")
   plot_i <- ggplot(Num, aes(Num[,i]))+ geom_histogram(fill="skyblue", col="Blue")+
                    ggtitle(names(Num)[i])+theme_classic()
   print(plot_i)
   dev.off()
}
kashj
  • 136
  • 8
  • _n.b._ when plotting multiple objects (like 2 or more DFs or similar), store them in a [list](https://stackoverflow.com/questions/28023427/applying-some-functions-to-multiple-objects) and then [lapply](https://stackoverflow.com/questions/54412460/r-using-lapply-to-save-plots) a function over them. – Ndharwood Feb 21 '22 at 19:28
-1

ggplot uses lazy evaluation and a for loop doesn't force() evaluation of your loop index. lapply does. So change your for loop to lapply.

My answer here gives more details.

Limey
  • 10,234
  • 2
  • 12
  • 32
  • But the ggsave should force the evaluation and that’s inside the loop. I’m not sure this is the case here. – MrFlick Jul 25 '20 at 07:33
  • @MrFlick. That was my first thought also. But, in the basence of a MWE, I took OP at their word. But using `mtcars %>% group_split(cyl)` to create a list of data frames, their code works as for me: three different plots in three different files. Perhaps the issue lay elsewhere. – Limey Jul 25 '20 at 09:21