diff --git a/NEWS.md b/NEWS.md index 54c56be6ea..4d796290b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -253,6 +253,11 @@ up correct aspect ratio, and draws a graticule. * `ggsave()`'s DPI argument now supports 3 string options: "retina" (320 DPI), "print" (300 DPI), and "screen" (72 DPI) (@foo-bar-baz-qux, #2156). +* Fixed partial argument matches in `ggsave()`. (#2355) + +* `ggsave()` now correctly restores the previous graphics device when several + graphics devices are open. (#2363) + * `print.ggplot()` now returns the original ggplot object, instead of the output from `ggplot_build()`. Also, the object returned from `ggplot_build()` now has the class `"ggplot_built"`. (#2034) diff --git a/R/save.r b/R/save.r index ea2875ffdb..7848f7e77e 100644 --- a/R/save.r +++ b/R/save.r @@ -53,8 +53,12 @@ ggsave <- function(filename, plot = last_plot(), if (!is.null(path)) { filename <- file.path(path, filename) } - dev(file = filename, width = dim[1], height = dim[2], ...) - on.exit(utils::capture.output(grDevices::dev.off())) + old_dev <- dev.cur() + dev(filename = filename, width = dim[1], height = dim[2], ...) + on.exit(utils::capture.output({ + grDevices::dev.off() + dev.set(old_dev) + })) grid.draw(plot) invisible() @@ -116,16 +120,16 @@ plot_dev <- function(device, filename, dpi = 300) { if (is.function(device)) return(device) - eps <- function(...) { - grDevices::postscript(..., onefile = FALSE, horizontal = FALSE, + eps <- function(filename, ...) { + grDevices::postscript(file = filename, ..., onefile = FALSE, horizontal = FALSE, paper = "special") } devices <- list( eps = eps, ps = eps, - tex = function(...) grDevices::pictex(...), - pdf = function(..., version = "1.4") grDevices::pdf(..., version = version), - svg = function(...) svglite::svglite(...), + tex = function(filename, ...) grDevices::pictex(file = filename, ...), + pdf = function(filename, ..., version = "1.4") grDevices::pdf(file = filename, ..., version = version), + svg = function(filename, ...) svglite::svglite(file = filename, ...), emf = function(...) grDevices::win.metafile(...), wmf = function(...) grDevices::win.metafile(...), png = function(...) grDevices::png(..., res = dpi, units = "in"), diff --git a/tests/testthat/test-ggsave.R b/tests/testthat/test-ggsave.R index abd8715920..7cd6fdb248 100644 --- a/tests/testthat/test-ggsave.R +++ b/tests/testthat/test-ggsave.R @@ -11,6 +11,26 @@ test_that("ggsave creates file", { expect_true(file.exists(path)) }) +test_that("ggsave restores previous graphics device", { + # When multiple devices are open, dev.off() restores the next one in the list, + # not the previously-active one. (#2363) + path <- tempfile() + on.exit(unlink(path)) + + png() + png() + on.exit({ + dev.off() + dev.off() + }, add = TRUE) + + old_dev <- dev.cur() + p <- ggplot(mpg, aes(displ, hwy)) + geom_point() + ggsave(path, p, device = "png", width = 5, height = 5) + + expect_identical(old_dev, dev.cur()) +}) + # plot_dim ---------------------------------------------------------------