59

I want to automate the generation of a number of ggplots:

Generic dataset:

mydata<-data.frame(matrix(rnorm(100),ncol=5))
names(mydata)<-c("Tijd","X1","X2","X3","X4") 

Specify variables to include:

Start=2
Stop=5

List to save the plots in:

gvec<-vector("list",length=length(Start:Stop))

Create plots:

for(i in Start:Stop){
  graphy<-ggplot(mydata,aes_string(x="Tijd",y=names(mydata)[i]))+geom_point()+mytheme
  gvec[[i-Start+1]]<-graphy
}

Save plots:

for(i in Start:Stop){
tiff(paste0("Test/Residu/Plots/Prei/mydata.",names(mydata)[i],"09.14.tiff"),width=720,height=720)
gvec[[i-Start+1]]
graphics.off()
}

The list of plots is generated; I can save the plots manually as well. However, using the last loop the files generated are all blank. I can't figure out the reason for this.

As per Roland's suggestion I tried print(gvec[[i-Start+1]]) but I still get blank files as output.

zx8754
  • 52,746
  • 12
  • 114
  • 209
Pinemangoes
  • 1,158
  • 3
  • 11
  • 13

3 Answers3

115

Here is a fully reproducible example of creating ggplots in a loop.

# Plot separate ggplot figures in a loop.
library(ggplot2)

# Make list of variable names to loop over.
var_list = combn(names(iris)[1:3], 2, simplify=FALSE)

# Make plots.
plot_list = list()
for (i in 1:3) {
    p = ggplot(iris, aes_string(x=var_list[[i]][1], y=var_list[[i]][2])) +
        geom_point(size=3, aes(colour=Species))
    plot_list[[i]] = p
}

# Save plots to tiff. Makes a separate file for each plot.
for (i in 1:3) {
    file_name = paste("iris_plot_", i, ".tiff", sep="")
    tiff(file_name)
    print(plot_list[[i]])
    dev.off()
}

# Another option: create pdf where each page is a separate plot.
pdf("plots.pdf")
for (i in 1:3) {
    print(plot_list[[i]])
}
dev.off()

enter image description here

bdemarest
  • 14,397
  • 3
  • 53
  • 56
  • This didn't work for me but the next answer down did, FWIW--perhaps it's out of date? – Bajcz Aug 31 '22 at 15:37
  • 1
    @Bajcz, The code in this answer still runs without error for me. Here is the partial output of `sessionInfo()` from my laptop: `R version 3.6.1 (2019-07-05) Running under: macOS Catalina 10.15.7 ggplot2_3.3.2`. As you can see, my R version is 3 years out of date. Maybe more recent changes have caused errors? – bdemarest Sep 26 '22 at 17:01
32

You can also use the ggsave function from ggplot2 library.

library(ggplot2)
data("iris")

# list of values to loop over
  uniq_species = unique(iris$Species)


# Loop

for (i in uniq_species) {

  temp_plot = ggplot(data= subset(iris, Species == i)) + 
                  geom_point(size=3, aes(x=Petal.Length, y=Petal.Width )) +
                  ggtitle(i)

  ggsave(temp_plot, file=paste0("plot_", i,".png"), width = 14, height = 10, units = "cm")
}
rafa.pereira
  • 13,251
  • 6
  • 71
  • 109
  • Reading this in 2022, this solution works better for me than the accepted answer FWIW. – Bajcz Aug 31 '22 at 15:37
  • Why does `ggsave` save plots with a **dark background** instead of the white one displayed in the panel of RStudio? – Julien Sep 21 '22 at 07:34
8

You can create and export the plots within the same loop. The combined code would be:

for(i in Start:Stop){
  graphy<-ggplot(mydata,aes_string(x="Tijd",y=names(mydata)[i]))+geom_point()+mytheme
  tiff(paste0("Test/Residu/Plots/Prei/mydata.",names(mydata)[i],"09.14.tiff"),width=720,height=720)
  print(graphy)
  dev.off()  
}

For a general case with stacked data, where the id variable correspond to the subgroup (country, individual, etc)):

for (i in 1:10) {
  mydata_id <- subset(mydata, id == i) # subselect group
  p <- ggplot(mydata_id, aes(x, y)) + geom_line() # create graph
  png(paste("plot_", i, ".png", sep = ""), width=600, height=500, res=120) # start export
  print(p) 
  dev.off() # finish export
}
luchonacho
  • 6,759
  • 4
  • 35
  • 52