-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* pull out plot_dim and add tests * save any object with grid.draw method * require filename
- Loading branch information
Showing
5 changed files
with
134 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,127 +1,112 @@ | ||
#' Save a ggplot with sensible defaults | ||
#' Save a ggplot (or other grid object) with sensible defaults | ||
#' | ||
#' ggsave is a convenient function for saving a plot. It defaults to | ||
#' saving the last plot that you displayed, and for a default size uses | ||
#' the size of the current graphics device. It also guesses the type of | ||
#' graphics device from the extension. This means the only argument you | ||
#' need to supply is the filename. | ||
#' \code{ggsave()} is a convenient function for saving a plot. It defaults to | ||
#' saving the last plot that you displayed, using the size of the current | ||
#' graphics device. It also guesses the type of graphics device from the | ||
#' extension. | ||
#' | ||
#' \code{ggsave} currently recognises the extensions eps/ps, tex (pictex), | ||
#' pdf, jpeg, tiff, png, bmp, svg and wmf (windows only). | ||
#' | ||
#' @param filename file name/filename of plot | ||
#' @param plot plot to save, defaults to last plot displayed | ||
#' @param device device to use, automatically extract from file name extension | ||
#' @param path path to save plot to (if you just want to set path and not | ||
#' filename) | ||
#' @param scale scaling factor | ||
#' @param width width (defaults to the width of current plotting window) | ||
#' @param height height (defaults to the height of current plotting window) | ||
#' @param units units for width and height when either one is explicitly specified (in, cm, or mm) | ||
#' @param dpi dpi to use for raster graphics | ||
#' @param limitsize when \code{TRUE} (the default), \code{ggsave} will not | ||
#' @param filename File name to create on disk. | ||
#' @param plot Plot to save, defaults to last plot displayed. | ||
#' @param device Device to use. By default, extracted from extension. | ||
#' \code{ggsave} currently recognises eps/ps, tex (pictex), pdf, jpeg, tiff, | ||
#' png, bmp, svg and wmf (windows only). | ||
#' @param path Path to save plot to (combined with filename). | ||
#' @param scale Multiplicative scaling factor. | ||
#' @param width,height Plot dimensions, defaults to size of current graphics | ||
#' device. | ||
#' @param units Units for width and height when specified explicitly (in, cm, | ||
#' or mm) | ||
#' @param dpi Resolution used for raster outputs. | ||
#' @param limitsize When \code{TRUE} (the default), \code{ggsave} will not | ||
#' save images larger than 50x50 inches, to prevent the common error of | ||
#' specifying dimensions in pixels. | ||
#' @param ... other arguments passed to graphics device | ||
#' @param ... Other arguments passed on to graphics device | ||
#' @export | ||
#' @examples | ||
#' \dontrun{ | ||
#' ratings <- ggplot(movies, aes(rating)) + | ||
#' geom_histogram() | ||
#' ggplot(movies, aes(length)) + | ||
#' geom_histogram() | ||
#' ggsave("length-hist.pdf") | ||
#' ggsave("length-hist.png") | ||
#' ggsave("ratings.pdf", ratings) | ||
#' ggsave("ratings.pdf", ratings, width=4, height=4) | ||
#' # make twice as big as on screen | ||
#' ggsave("ratings.pdf", ratings, scale=2) | ||
#' ggplot(movies, aes(rating)) + geom_histogram(binwidth = 0.1) | ||
#' | ||
#' ggsave("ratings.pdf") | ||
#' ggsave("ratings.pdf") | ||
#' | ||
#' ggsave("ratings.pdf", width = 4, height = 4) | ||
#' ggsave("ratings.pdf", width = 20, height = 20, units = "cm") | ||
#' | ||
#' unlink("ratings.pdf") | ||
#' unlink("ratings.png") | ||
#' } | ||
ggsave <- function(filename = default_name(plot), plot = last_plot(), | ||
device = default_device(filename), path = NULL, scale = 1, | ||
width = par("din")[1], height = par("din")[2], units = c("in", "cm", "mm"), | ||
dpi = 300, limitsize = TRUE, ...) { | ||
|
||
if (!inherits(plot, "ggplot")) stop("plot should be a ggplot2 plot") | ||
ggsave <- function(filename, plot = last_plot(), | ||
device = default_device(filename), path = NULL, scale = 1, | ||
width = NA, height = NA, units = c("in", "cm", "mm"), | ||
dpi = 300, limitsize = TRUE, ...) { | ||
|
||
eps <- ps <- function(..., width, height) | ||
grDevices::postscript(..., width=width, height=height, onefile=FALSE, | ||
grDevices::postscript(..., width = width, height = height, onefile = FALSE, | ||
horizontal = FALSE, paper = "special") | ||
tex <- function(..., width, height) | ||
grDevices::pictex(..., width=width, height=height) | ||
pdf <- function(..., version="1.4") | ||
grDevices::pdf(..., version=version) | ||
grDevices::pictex(..., width = width, height = height) | ||
pdf <- function(..., version = "1.4") | ||
grDevices::pdf(..., version = version) | ||
svg <- function(...) | ||
grDevices::svg(...) | ||
wmf <- function(..., width, height) | ||
grDevices::win.metafile(..., width=width, height=height) | ||
grDevices::win.metafile(..., width = width, height = height) | ||
emf <- function(..., width, height) | ||
grDevices::win.metafile(..., width=width, height=height) | ||
|
||
grDevices::win.metafile(..., width = width, height = height) | ||
png <- function(..., width, height) | ||
grDevices::png(..., width=width, height=height, res = dpi, units = "in") | ||
grDevices::png(..., width = width, height = height, res = dpi, units = "in") | ||
jpg <- jpeg <- function(..., width, height) | ||
grDevices::jpeg(..., width=width, height=height, res = dpi, units = "in") | ||
grDevices::jpeg(..., width = width, height = height, res = dpi, units = "in") | ||
bmp <- function(..., width, height) | ||
grDevices::bmp(..., width=width, height=height, res = dpi, units = "in") | ||
grDevices::bmp(..., width = width, height = height, res = dpi, units = "in") | ||
tiff <- function(..., width, height) | ||
grDevices::tiff(..., width=width, height=height, res = dpi, units = "in") | ||
|
||
default_name <- function(plot) { | ||
paste(digest.ggplot(plot), ".pdf", sep="") | ||
} | ||
grDevices::tiff(..., width = width, height = height, res = dpi, units = "in") | ||
|
||
default_device <- function(filename) { | ||
pieces <- strsplit(filename, "\\.")[[1]] | ||
ext <- tolower(pieces[length(pieces)]) | ||
match.fun(ext) | ||
} | ||
|
||
units <- match.arg(units) | ||
convert_to_inches <- function(x, units) { | ||
x <- switch(units, | ||
`in` = x, | ||
cm = x / 2.54, | ||
mm = x / 2.54 /10 | ||
) | ||
} | ||
dim <- plot_dim(c(width, height), scale = scale, units = units, | ||
limitsize = limitsize) | ||
|
||
convert_from_inches <- function(x, units) { | ||
x <- switch(units, | ||
`in` = x, | ||
cm = x * 2.54, | ||
mm = x * 2.54 * 10 | ||
) | ||
if (!is.null(path)) { | ||
filename <- file.path(path, filename) | ||
} | ||
device(file = filename, width = dim[1], height = dim[2], ...) | ||
on.exit(capture.output(dev.off())) | ||
grid.draw(plot) | ||
|
||
# dimensions need to be in inches for all graphic devices | ||
# convert width and height into inches when they are specified | ||
if (!missing(width)) { | ||
width <- convert_to_inches(width, units) | ||
} | ||
if (!missing(height)) { | ||
height <- convert_to_inches(height, units) | ||
} | ||
# if either width or height is not specified, display an information message | ||
# units are those specified by the user | ||
if (missing(width) || missing(height)) { | ||
message("Saving ", prettyNum(convert_from_inches(width * scale, units), digits=3), " x ", prettyNum(convert_from_inches(height * scale, units), digits=3), " ", units, " image") | ||
} | ||
invisible() | ||
} | ||
|
||
plot_dim <- function(dim = c(NA, NA), scale = 1, units = c("in", "cm", "mm"), | ||
limitsize = TRUE, dim_guess = FALSE) { | ||
|
||
|
||
units <- match.arg(units) | ||
to_inches <- function(x) x / c(`in` = 1, cm = 2.54, mm = 2.54 * 10)[units] | ||
from_inches <- function(x) x * c(`in` = 1, cm = 2.54, mm = 2.54 * 10)[units] | ||
|
||
width <- width * scale | ||
height <- height * scale | ||
dim <- to_inches(dim) * scale | ||
|
||
if (limitsize && (width >= 50 || height >= 50)) { | ||
stop("Dimensions exceed 50 inches (height and width are specified in inches/cm/mm, not pixels).", | ||
" If you are sure you want these dimensions, use 'limitsize=FALSE'.") | ||
if (any(is.na(dim))) { | ||
dim[is.na(dim)] <- par("din") * scale | ||
dim_f <- prettyNum(from_inches(dim), digits = 3) | ||
message("Saving ", dim_f[1], " x ", dim_f[2], " ", units, " image") | ||
} | ||
|
||
if (!is.null(path)) { | ||
filename <- file.path(path, filename) | ||
if (limitsize && any(dim >= 50)) { | ||
stop("Dimensions exceed 50 inches (height and width are specified in '", | ||
units, "' not pixels). If you're sure you a plot that big, use ", | ||
"`limitsize = FALSE`.", call. = FALSE) | ||
} | ||
device(file=filename, width=width, height=height, ...) | ||
on.exit(capture.output(dev.off())) | ||
print(plot) | ||
|
||
invisible() | ||
dim | ||
} | ||
|
||
#' @export | ||
grid.draw.ggplot <- function(x, recording = TRUE) { | ||
print(x) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
context("ggsave") | ||
|
||
|
||
# plot_dim --------------------------------------------------------------- | ||
|
||
test_that("guesses and informs if dim not specified", { | ||
png(width = 10, height = 10, units = "in", res = 300) | ||
on.exit(capture.output(dev.off())) | ||
|
||
expect_message(out <- plot_dim(), "10 x 10") | ||
expect_equal(out, c(10, 10)) | ||
}) | ||
|
||
test_that("warned about large plot unless limitsize = FALSE", { | ||
expect_error(plot_dim(c(50, 50)), "exceed 50 inches") | ||
expect_equal(plot_dim(c(50, 50), limitsize = FALSE), c(50, 50)) | ||
}) | ||
|
||
test_that("scale multiplies height & width", { | ||
expect_equal(plot_dim(c(10, 10), scale = 1), c(10, 10)) | ||
expect_equal(plot_dim(c(5, 5), scale = 2), c(10, 10)) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters