I'm not sure if this question is still active, but this is the first one that appeared when searching for “saving graphs in a brilliant application”, so I would like to quickly add how to get ggsave to work with downloadHandler along the lines of the original question,
The alternative strategies suggested by juba using direct output instead of ggsave and the alternative strategy suggested by alexwhan both work fine, it's just for those who absolutely want to use ggsave in downloadHandler).
The problem reported by alexwhan is because ggsave is trying to map the file extension to the correct graphics device. However, the temporary file has no extension, so the match does not occur. This can be eliminated by specially configuring the device in the ggsave function ggsave , for example, in the source code example (for png):
output$downloadPlot <- downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { device <- function(..., width, height) grDevices::png(..., width = width, height = height, res = 300, units = "in") ggsave(file, plot = plotInput(), device = device) } )
This call basically accepts the device function for png , which ggsave assigns internally (you can look at the ggsave function code to see the syntax jpg , pdf , etc.). Perhaps, ideally, you could specify the file extension (if it differs from the file name - as is the case here for the temporary file) as the ggsave parameter, but this option is not currently available in ggsave .
Minimal standalone working example:
library(shiny) library(ggplot2) runApp(list( ui = fluidPage(downloadButton('foo')), server = function(input, output) { plotInput = function() { qplot(speed, dist, data = cars) } output$foo = downloadHandler( filename = 'test.png', content = function(file) { device <- function(..., width, height) { grDevices::png(..., width = width, height = height, res = 300, units = "in") } ggsave(file, plot = plotInput(), device = device) }) } )) sessionInfo()
Update
In ggplot2 version 2.0.0, the ggsave function supports character input for the device parameter, which means that the temporary file created by downloadHandler can now be saved by calling ggsave , indicating that the extension used should be, for example, "pdf" (instead device function transfer). This simplifies the above example to the following
output$downloadPlot <- downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { ggsave(file, plot = plotInput(), device = "png") } )