Passing a ggplot2 call to ggsave

I am curious what people think of this behaviour. Is this intended? Is there a better way to solve this? Feels like it could be a bug if it wasn't such an obvious application.


## "normal" way of doing this
p <- ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +

ggsave("foo.png", plot = p)
#> Saving 7 x 5 in image

## Doesn't work even though it feels like it should. What geom_point returns 
## is what is passed to ggsave
p_save <- ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +
  geom_point() %>% 
  ggsave("foo2.png", plot = .)
#> Saving 7 x 5 in image
#> Error in UseMethod("grid.draw"): no applicable method for 'grid.draw' applied to an object of class "c('LayerInstance', 'Layer', 'ggproto', 'gg')"

## Instead you have to surround the whole ggplot2 call in parens
p_save_parens <- (ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +
             geom_point()) %>% 
  ggsave("foo3.png", plot = .)
#> Saving 7 x 5 in image

Created on 2020-03-12 by the reprex package (v0.3.0)

1 Like

The default for ggsave is the last plot displayed. Surrounding the statement with the parens causes it to be displayed as well as assigned and then passed on to ggsave, and the plot argument is unnecessary because the immediate statement ensures that the subject plot is, indeed, the last one saved.


Oh interesting! Is this the best way to pipe a ggplot into ggsave? Can you recommend any others? My goal is to create a ggplot and save all in one call.

I think it's the only way (although, as always, I might be wrong!) to do it in a pipe at one pass. Because ggsave takes a plot argument in place of the default last saved you'd need

my_plot <- ggplot(...)
ggsave(my_plot, ...)


my_func (f to create a succession of plots somehow and save names in df.)
my_save (f to pass names of files constructed from plot names)
purrr::map(df., my_save)

Thanks for taking the trouble to mark a solution for the benefit of those to follow. And I forgot to thank you for the great reprex.

1 Like

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