Skip to content

Commit 0c06945

Browse files
committed
allow dimensions to be derived from plot
1 parent 11f6cd0 commit 0c06945

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

R/save.R

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,12 @@ ggsave <- function(filename, plot = get_last_plot(),
9999

100100
dpi <- parse_dpi(dpi)
101101
dev <- validate_device(device, filename, dpi = dpi)
102-
dim <- plot_dim(c(width, height), scale = scale, units = units,
103-
limitsize = limitsize, dpi = dpi)
102+
dim <- plot_dim(
103+
width = width, height = height,
104+
scale = scale, units = units,
105+
limitsize = limitsize, dpi = dpi,
106+
plot = plot
107+
)
104108

105109
if (is_null(bg)) {
106110
bg <- calc_element("plot.background", plot_theme(plot))$fill %||% "transparent"
@@ -189,12 +193,44 @@ parse_dpi <- function(dpi, call = caller_env()) {
189193
}
190194
}
191195

192-
plot_dim <- function(dim = c(NA, NA), scale = 1, units = "in",
193-
limitsize = TRUE, dpi = 300, call = caller_env()) {
196+
plot_dim <- function(width = NA, height = NA, scale = 1, units = "in",
197+
limitsize = TRUE, dpi = 300, plot = NULL, call = caller_env()) {
194198
units <- arg_match0(units, c("in", "cm", "mm", "px"))
195-
to_inches <- function(x) x / c(`in` = 1, cm = 2.54, mm = 2.54 * 10, px = dpi)[units]
199+
to_inches <- function(x) x / c(`in` = 1, cm = 2.54, mm = 2.54 * 10, px = dpi)[units]
196200
from_inches <- function(x) x * c(`in` = 1, cm = 2.54, mm = 2.54 * 10, px = dpi)[units]
197201

202+
if (is.derived(width) || is.derived(height)) {
203+
if (is.ggplot(plot)) {
204+
plot <- ggplotGrob(plot)
205+
}
206+
if (!inherits(plot, "gtable")) {
207+
cli::cli_abort(
208+
"Cannot derive size of plot when {.arg plot} is \\
209+
{.obj_type_friendly {plot}}.",
210+
call = call
211+
)
212+
}
213+
width <- if (is.derived(width)) gtable_width(plot) else width
214+
height <- if (is.derived(height)) gtable_height(plot) else height
215+
}
216+
217+
if (is.unit(width)) {
218+
if (has_null_unit(width)) {
219+
width <- NA
220+
} else {
221+
width <- from_inches(convertWidth(width, "in", valueOnly = TRUE))
222+
}
223+
}
224+
225+
if (is.unit(height)) {
226+
if (has_null_unit(height)) {
227+
height <- NA
228+
} else {
229+
height <- from_inches(convertHeight(height, "in", valueOnly = TRUE))
230+
}
231+
}
232+
233+
dim <- c(width, height)
198234
dim <- to_inches(dim) * scale
199235

200236
if (anyNA(dim)) {

tests/testthat/_snaps/ggsave.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
# warned about large plot unless limitsize = FALSE
3737

3838
Code
39-
plot_dim(c(50, 50))
39+
plot_dim(50, 50)
4040
Condition
4141
Error:
4242
! Dimensions exceed 50 inches (`height` and `width` are specified in inches not pixels).
@@ -45,7 +45,7 @@
4545
---
4646

4747
Code
48-
plot_dim(c(15000, 15000), units = "px")
48+
plot_dim(15000, 15000, units = "px")
4949
Condition
5050
Error:
5151
! Dimensions exceed 50 inches (`height` and `width` are specified in pixels).

tests/testthat/test-ggsave.R

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,15 @@ test_that("uses 7x7 if no graphics device open", {
112112
})
113113

114114
test_that("warned about large plot unless limitsize = FALSE", {
115-
expect_snapshot(plot_dim(c(50, 50)), error = TRUE)
116-
expect_equal(plot_dim(c(50, 50), limitsize = FALSE), c(50, 50))
117-
expect_snapshot(plot_dim(c(15000, 15000), units = "px"), error = TRUE)
115+
expect_snapshot(plot_dim(50, 50), error = TRUE)
116+
expect_equal(plot_dim(50, 50, limitsize = FALSE), c(50, 50))
117+
expect_snapshot(plot_dim(15000, 15000, units = "px"), error = TRUE)
118118
})
119119

120120
test_that("scale multiplies height & width", {
121-
expect_equal(plot_dim(c(10, 10), scale = 1), c(10, 10))
122-
expect_equal(plot_dim(c(5, 5), scale = 2), c(10, 10))
121+
expect_equal(plot_dim(10, 10, scale = 1), c(10, 10))
122+
expect_equal(plot_dim(5, 5, scale = 2), c(10, 10))
123+
})
123124
})
124125

125126
# plot_dev ---------------------------------------------------------------------

0 commit comments

Comments
 (0)