rggplot2shinyggsave

Save ggplot from Shiny to a folder of my choosing and with a name of my choosing


I have an R Shiny document where a user defines their chosen data and parameters, colours, etc. for a ggplot plot that is displayed in a "PlotOutput" area.

I want to add a button that will save the image that is currently in a plotting area as a PNG to a folder that I have already defined and with a naming format that I have chosen.

Namely, I would like the file to have name like "IMG_YYMMDD_HHMMSS" where date and time information comes from a Sys.time() call.

The only thing similar that I'm seeing documentation for is a downloadButton widget. But I can't get this to work, and even if I could, this lets the user define the name and destination of the output image file, which is not what I want.*

If I could just have the ggplot object passed to a ggsave function like one would do if one was writing code to produce such an image, then the file name and file path could be defined in this way. Is there any way to just do this?

Cheers

EDIT: so it looks like there is a way of using the download handler to save with a default name of my choosing. For my purposes, it looks to be easily changed from the below example:

output$downloadData <- downloadHandler(
  filename = function() { 
    paste(input$downloadData, " ",Sys.Date(),".csv",sep="") 
  },
  content = function(file) {
    write.csv(myout()$dataframe1,file,row.names=F)
  }
)

But I'm still not clear about how to use it and if there is a way of setting a folder of my choosing as the default as well. That would be perfect if it could be done.

*the reason I don't want it this way is that it should be very quick. It should take 10 seconds to produce the image that the user desires. If they then need to spend 15 seconds saving the image to some random destination with a random name, then this defeats the point. The idea is that it should just be the last name alphabetically, and the date and time works for this.


Solution

  • I wasn't able to do everything that I wanted, but this answer had enough to get me close enough.

    The trick was to create the ggplot object as a reactive dataset that is

    1. passed to the renderer in

      output$dotPlot <- renderPlot({
          p()
      })
      

    and 2. passed into the download handler in

    output$save <- downloadHandler(
      filename =  function() {
        "WhatIWantToCallMyFile.png"
      },
      # content is a function with argument file. content writes the plot to the device
      content = function(file) {
        ggsave(file, p())
      } 
    )
    

    Saving ggplot from Shiny gives blank png file

    This saves a nicely high res image as it's default anyway, but you can tinker around with width and height within ggsave.