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.
library(ggplot2)
library(magrittr)
## "normal" way of doing this
p <- ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +
geom_point()
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
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, ...)
or
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)