Saving 100s of ggplots from RStudio automatically (simultaneously)

Hi RStudio experts,

I have created 100's of ggplot in RStudio and want to save them in my folder.
So, literally, I can see all the plots 1 by 1 in "Plots".
I could save 1 by 1 using "Export" but it takes long time.

So, is there a better way to save plots from RStudio (if possible with Unique name and png format
P.S: Similar Question here

Thanks in advance,
Abi

It depends on how the hundreds of plots (really though?) are created.
Are they generated one by one with a new bit of code for each plot, or is it some sort of a function output?

those plots are all ggplots and they are created 1 by 1 from morning but didnt save them.
Instead of spending another day, I would like to save my work. Please help me :slight_smile:

This sounds pretty scary. To have it done quickly in the current manual workflow, I'd just slap a ggsave() right after every ggplot plot. If your plots are assigned to objects, you can use the object names as your file names. Else... IDK, just go "1,2,3,4...100" :man_shrugging:?

Any better solutions from anyone, good people?

1 Like

Thanks for suggestion. In the link shared, they talk about SavedPlots and saving via temparary files but doesnt seems to work for me at all.
Mine is Windows but I am working on AWS instance (RStudio).

You should write a function that takes in data and a string, makes the plot, then uses ggsave to save them in a place given by the string. Save them in a non-temporary folder so you can view them later.

Save them as a smaller .png if you want speed.

1 Like

Thanks for recommendation.
I am basically saving holt time series forecasts of the time series data I send to my function below.
based on the key and pair, ggplot gets the uinique name title.

Could you please guide me where I should use ggsave ?
Should I ggsave for complete function or 1 by 1 within the function itself.
Should I remove print from ggplot ?

# Function to plot 10 ggplots within function
myFunc <- function(ts= someValue, key = "someValue1", pair = "someValue2"){
            eg1 <- ts[,1] %>% holt(h=5, damped = T) ### Holt time series forecast
            print(ggplot2:: autoplot(holt_method) + ## Print in order to display in plots window
			ggtitle(paste(key,pair)) 
			eg2 <- ts[,2] %>% holt(h=5, damped = T) ### Holt time series forecast
            print(ggplot2:: autoplot(holt_method) +
			ggtitle(paste(key,pair)) 
			.......
			eg10 <- ts[,10] %>% holt(h=5, damped = T) ### Holt time series forecast
            print(ggplot2:: autoplot(holt_method) +
			ggtitle(paste(key,pair))
        }

you should be able to just ggsave at the bottm, I think. I think you als omentioend that you want unique names. Assuming you have a folder called "plots" on your desktop, you can put them all in there but adding something like this:

filename = paste('~/Desktop/`,key, pair, '.png', sep = '')
ggsave(filename)

ggsave saves only the most recent plot. So either you assign it to a variable first:
e.g.: plot = ggplot2:: autoplot(holt_method) + ## Print in order to display in plots window
ggtitle(paste(key,pair))
...
and then followed by ggsave(plot = plot, paste0("~/Desktop/",key, pair, ".png",
width = XX, height = YY, units = "cm") (or "in" if you prefer) (I usually define the size, as the automatic save sometimes leads to strange results)

or maybe you can wrap everything you have now in the print() into the ggsave() function. Not sure, never tested this.

Here's a bit of refactoring of your myFunc() function that may fit your needs.

plot_holt_forecast <- function(ts, key = "key-value", pair = "pair-value", outdir = getwd()) {
  library(ggplot2)

  ncol_time_series <- ncol(ts)
  for (index in seq_len(ncol_time_series)) {
    holt_forecast <- holt(ts[, index], h = 5, damped = TRUE)
    
    holt_plot <- autoplot(holt_forecast) +
      ggtitle(paste(key, pair, index, sep = " - "))
    
    outfile <- sprintf("%s_%s_%03d.pdf", key, pair, index)
    ggsave(filename = file.path(outdir, outfile), holt_plot)
  }
}

I assumed that you want to iterate over each of the columns of ts. So for each column in ts, the function applies holt() to get the holt_forecast and then uses autoplot() to create a ggplot. Rather than printing the plot, it is assigned to the variable holt_plot.

Then, the function uses key, pair, and index (the column number) to create a unique filename for the plot, which is saved into the working directory as a pdf.

If you need to change the output format, you can replace ".pdf" with ".png" or similar, and you can also add options to ggsave() to change settings like output dimensions, such as width = 10 and height = 8 to get a 10x8in plot. Look at the help page for ?ggsave for more ideas there.

So if you run the following on ts data with 10 columns, you'll end up with 10 files saved to your working directory.

plot_holt_forecast(ts, "key1", "pair1")

# key1_pair1_001.pdf
# key1_pair1_002.pdf
# ...

Thanks for descriptive and creative approach.
I tried your approach as we see the image being created message "Saving 8.28 x 5.35 in image" in console and in files we could also see files saved but when we click on pdf.
pdf saves "/*folder.pdf not found"

Am I doing something weird ?

Thanks @limacina and @Matthias for suggestion. Actually I tried both within function and outside. Either way, there is no saving instead error: "could not open file "Desktop/keypair.png" "

At this point, it's very hard to tell why you're getting the error. If it's possible for you to post example data I may be able to help further. Also, please share the code that you used to run the function.

In the mean time, here's another version of the function that can be applied to built in data sets, like iris

plot_histograms <- function(df, key = "key-value", pair = "pair-value", outdir = getwd()) {
  library(ggplot2)
  
  ncol_df <- ncol(df)
  for (index in seq_len(ncol_df)) {
    # do whatever needs to be done here to produce a plot for a column
    # I'm using qplot() just to make things easy
    g <- qplot(x = df[, index], bins = 10) +
      ggtitle(paste(key, pair, index, sep = " - "))
    
    outfile <- sprintf("%s_%s_%03d.pdf", key, pair, index)
    ggsave(filename = file.path(outdir, outfile), g)
  }
}

# Run on iris
plot_histograms(iris, "Key", "Pair")
## Saving 7.12 x 8.33 in image
## Saving 7.12 x 8.33 in image
## Saving 7.12 x 8.33 in image
## Saving 7.12 x 8.33 in image
## Warning: Ignoring unknown parameters: bins
## Saving 7.12 x 8.33 in image

As you can tell from the output, 5 plots were created and then saved to my working directory with names like Key_Pair_001.pdf, looking like this:

1 Like

I get the simliar error: "unable to open file '...'" when I try to save to a file that doesn't exist. Have you tried using getwd() to make sure you are where you think you are, and setwd() to get yousrelf to the Desktop (or the folder where you want to save the files)? If you do that then you don't need anything before the name of the file in ggsave (just ggsave('keypair.png").

Thanks @grrrck for solution.
Actually, images are generated and storted in the folder with size about 100KB.
But when I click on the files, there is no display of image
But if I exported (download) locally, images can be opened

Is it because Rstudio via AWS works doesnt render saved images

Thanks @limacina for explaining to give the appropriate folder path. Yes, it does saved in different folder.
I tried both embedding after each ggplot within function and outside the function.
In either case, only the latest plot is saved and only 1 plot. So, @grrrck solution of using index would save all the plots.

filename = paste('/home/uia68633/R/UHP/uhp',key,pair '.png', sep = '')
              ggsave(filename)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.