I want to save the output of stats::heatmap() in ggplot2::ggsave(), but the output is not a plot, and I receive an error. Here is the code:
data("iris")
col<- colorRampPalette(c("blue", "white", "red"))(20)
ggsave(filename = "heatmap.png", plot = heatmap(x = cor(iris[,-5])  , col = col, symm = TRUE),device = "png", dpi = 450)
Now while the code actually works and saves the heatmap.png in the R working directory, it also returns an error. 
Saving 3.74 x 8.49 in image Error in UseMethod("grid.draw") : no applicable method for 'grid.draw' applied to an object of class "list"
I reckon it is because the output of heatmap() is not a plot and it is a list. 
Since I am using the ggsave() as part of a downloadHandler() in Shiny, the error  interrupts the downloading/saving process. 
I would appreciate your help
The syntax of ggsave() is
ggsave(filename, plot = last_plot(), device = NULL, path = NULL,
  scale = 1, width = NA, height = NA, units = c("in", "cm", "mm"),
  dpi = 300, limitsize = TRUE, ...)
The plot to be stored must be passed as the second argument. In order to do that you must be able to assign your plot to a variable. This can be done with plots created by ggplot():
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point()
class(p)
## [1] "gg"     "ggplot"
This piece of code does not show any plot, but it has actually stored a plot in p. You can render it by just running p or print(p).
Base plot functions are different. They directly create a plot as a side effect. So this code will show the plot, even though the output is assigned to a variable:
p2 <- heatmap(x = cor(iris[, -5]), col = col, symm = TRUE)
And p2 is now a list and not a plot:
p2
## $rowInd
## [1] 2 1 3 4
## 
## $colInd
## [1] 2 1 3 4
##  
## $Rowv
## NULL
## 
## $Colv
## NULL
So, passing p2 to ggsave() won't work because it does not actually contain the plot.
But it is still possible to store base plots in files by using graphics devices.
For example, you can create a png-file like this:
png(filename = "heatmap.png")
heatmap(x = cor(iris[, -5]), col = col, symm = TRUE)
dev.off()
And there are other devices that can be used similarly, e.g., jpeg(), pdf(), and tiff().
You can use the device in downloadHandler() as follows:
output$downloadData <- downloadHandler(
    filename = "heatmap.png",
    content = function(file) {
      png(filename = file)
      col <- colorRampPalette(c("blue", "white", "red"))(20)
      heatmap(x = cor(iris[, -5]), col = col, symm = TRUE)
      dev.off()
    }
  )
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With