9

I can save a plot with ggsave after I stored it, but using it in a pipeline I get the following error. I wish to plot and save in the same (piped) command.

  no applicable method for 'grid.draw' applied to an object of class "c('LayerInstance', 'Layer', 'ggproto', 'gg')" 

I know ggsave's arguments are first the filename, and then the plot, but switching this in a wrapper does not work. Also, using 'filename=' and 'plot=' in the ggsave command does not work.

library(magrittr)
library(ggplot2)
data("diamonds")

# my custom save function
customSave <- function(plot){
    ggsave('blaa.bmp', plot)
}

#This works:
p2 <- ggplot(diamonds, aes(x=cut)) + geom_bar()
p2 %>% customSave()

# This doesn't work:
ggplot(diamonds, aes(x=cut)) + geom_bar() %>% customSave()

# and obviously this doesn't work either
ggplot(diamonds, aes(x=cut)) + geom_bar() %>% ggsave('plot.bmp')
fliestech
  • 165
  • 2
  • 9
  • 3
    Try `(ggplot(diamonds, aes(x=cut)) + geom_bar()) %>% ggsave(filename = "plot.bmp")` – akrun Feb 12 '19 at 10:46
  • 1
    It works, but doesn't this oppose the idea of using forward pipes? – fliestech Feb 12 '19 at 10:52
  • 4
    The + isn't a pipe but a ggplot2 symbol. When leaving the () away, you give geom_bar() to ggsave() which causes an error as ggsave() needs a ggplot-object. Adding the () creates the plot first and hands it then over to ggsave(). – Benjamin Schlegel Feb 12 '19 at 13:06

2 Answers2

7

As akrun pointed out, you need to wrap all of your ggplot in parentheses. You can also use the dot notation to pass an object to a function parameter other than the first in a magrittr pipe stream:

library(magrittr)
library(ggplot2)
data("diamonds")

(
  ggplot(diamonds, aes(x=cut)) +
    geom_bar()
) %>% 
  ggsave("plot.png", . , dpi = 100, width = 4, height = 4)
DanTan
  • 660
  • 7
  • 17
6

Update: The following code no longer works. See the tidyverse GitHub issue and another StackOverflow question for the official solution.

Original answer that NO LONGER WORKS:

If you want to plot and save in one line, try this

ggsave('plot.bmp') ```

If you don't want to show the plot, simply put `p <- ` at the
beginning. 

If you have a custom save function, you can also do this

``` mysave <- function(filename) {   ggsave(file.path("plots",
paste0(filename, ".png")), 
         width = 8, height = 6, dpi = 300) } ```

and simply replace `ggsave('plot.bmp')` with `mysave('plot')` in the
snippet above.

I found this usage by accident but haven't found any documentation.
Jiageng
  • 148
  • 1
  • 7
  • 1
    If I follow your first suggestion I get another error: ´Error: Can't add `ggsave(filename = "file.png", ` to a ggplot object. * Can't add ` width = 9, height = 6)` to a ggplot object.´ – user3072843 Feb 09 '22 at 16:52
  • @user3072843 This no longer works. See https://stackoverflow.com/questions/68003633/error-cant-add-ggsave-to-a-ggplot-object and https://github.com/tidyverse/ggplot2/issues/4513 – Jiageng Mar 24 '22 at 21:08