Skip to content

Commit fd9830e

Browse files
authored
Merge branch 'main' into convert_linetype_nas
2 parents db1d0cd + 5b99d3c commit fd9830e

19 files changed

+157
-32
lines changed

NEWS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
* `linetype = NA` is now interpreted to mean 'no line' instead of raising errors
44
(@teunbrand, #6269).
5+
* (internal) layer data can be attenuated with parameter attributes
6+
(@teunbrand, #3175).
7+
* Date scales silently coerce <POSIXct> to <Date> and datetime scales silently
8+
coerce <Date> to <POSIXct> (@laurabrianna, #3533)
59
* New parameters for `geom_label()` (@teunbrand and @steveharoz, #5365):
610
* The `linewidth` aesthetic is now applied and replaces the `label.size`
711
argument.
@@ -304,10 +308,14 @@
304308
particularly for data-points with a low radius near the center
305309
(@teunbrand, #5023).
306310
* All scales now expose the `aesthetics` parameter (@teunbrand, #5841)
311+
* Staged expressions are handled more gracefully if legends cannot resolve them
312+
(@teunbrand, #6264).
307313
* New `theme(legend.key.justification)` to control the alignment of legend keys
308314
(@teunbrand, #3669).
309315
* Added `scale_{x/y}_time(date_breaks, date_minor_breaks, date_labels)`
310316
(@teunbrand, #4335).
317+
* `ggsave()` can write a multi-page pdf file when provided with a list of plots
318+
(@teunbrand, #5093).
311319

312320
# ggplot2 3.5.1
313321

R/geom-.R

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,15 @@ Geom <- ggproto("Geom",
163163
# If any after_scale mappings are detected they will be resolved here
164164
# This order means that they will have access to all default aesthetics
165165
if (length(modifiers) != 0) {
166-
# Set up evaluation environment
167-
modified_aes <- eval_aesthetics(
168-
substitute_aes(modifiers), data,
169-
mask = list(stage = stage_scaled)
166+
modified_aes <- try_fetch(
167+
eval_aesthetics(
168+
substitute_aes(modifiers), data,
169+
mask = list(stage = stage_scaled)
170+
),
171+
error = function(cnd) {
172+
cli::cli_warn("Unable to apply staged modifications.", parent = cnd)
173+
data_frame0()
174+
}
170175
)
171176

172177
# Check that all output are valid data
@@ -177,10 +182,7 @@ Geom <- ggproto("Geom",
177182
)
178183

179184
modified_aes <- cleanup_mismatched_data(modified_aes, nrow(data), "after_scale")
180-
181-
modified_aes <- data_frame0(!!!modified_aes)
182-
183-
data <- data_frame0(!!!defaults(modified_aes, data))
185+
data[names(modified_aes)] <- modified_aes
184186
}
185187

186188
# Override mappings with params

R/geom-crossbar.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ geom_crossbar <- function(mapping = NULL, data = NULL,
6060
#' @export
6161
GeomCrossbar <- ggproto("GeomCrossbar", Geom,
6262
setup_params = function(data, params) {
63-
if (lifecycle::is_present(params$fatten)) {
63+
if (lifecycle::is_present(params$fatten %||% deprecated())) {
6464
deprecate_soft0(
6565
"3.6.0", "geom_crossbar(fatten)",
6666
"geom_crossbar(middle.linewidth)"

R/geom-pointrange.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ GeomPointrange <- ggproto("GeomPointrange", Geom,
4242
required_aes = c("x", "y", "ymin|xmin", "ymax|xmax"),
4343

4444
setup_params = function(data, params) {
45-
if (lifecycle::is_present(params$fatten)) {
45+
if (lifecycle::is_present(params$fatten %||% deprecated())) {
4646
deprecate_soft0("3.6.0", "geom_pointrange(fatten)", I("the `size` aesthetic"))
4747
} else {
4848
# For backward compatibility reasons

R/geom-ribbon.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ GeomRibbon <- ggproto("GeomRibbon", Geom,
183183
if ((length(aes$fill) > 1 || length(aes$alpha) > 1)) {
184184
transformed <- coord$transform(flip_data(data, flipped_aes), panel_params)
185185
if (flipped_aes) {
186-
keep <- is.finite(tranformed$y)
186+
keep <- is.finite(transformed$y)
187187
args <- list(
188188
colours = alpha(data$fill, data$alpha)[keep],
189189
stops = rescale(transformed$y)[keep],

R/layer.R

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -347,12 +347,13 @@ Layer <- ggproto("Layer", NULL,
347347
},
348348

349349
compute_statistic = function(self, data, layout) {
350-
if (empty(data))
351-
return(data_frame0())
350+
if (empty(data)) return(data_frame0())
352351

352+
ptype <- vec_ptype(data)
353353
self$computed_stat_params <- self$stat$setup_params(data, self$stat_params)
354354
data <- self$stat$setup_data(data, self$computed_stat_params)
355-
self$stat$compute_layer(data, self$computed_stat_params, layout)
355+
data <- self$stat$compute_layer(data, self$computed_stat_params, layout)
356+
merge_attrs(data, ptype)
356357
},
357358

358359
map_statistic = function(self, data, plot) {
@@ -396,30 +397,32 @@ Layer <- ggproto("Layer", NULL,
396397
stat_data <- plot$scales$transform_df(stat_data)
397398
}
398399
stat_data <- cleanup_mismatched_data(stat_data, nrow(data), "after_stat")
399-
400-
data_frame0(!!!defaults(stat_data, data))
400+
data[names(stat_data)] <- stat_data
401+
data
401402
},
402403

403404
compute_geom_1 = function(self, data) {
404405
if (empty(data)) return(data_frame0())
406+
ptype <- vec_ptype(data)
405407

406408
check_required_aesthetics(
407409
self$geom$required_aes,
408410
c(names(data), names(self$aes_params)),
409411
snake_class(self$geom)
410412
)
411413
self$computed_geom_params <- self$geom$setup_params(data, c(self$geom_params, self$aes_params))
412-
self$geom$setup_data(data, self$computed_geom_params)
414+
data <- self$geom$setup_data(data, self$computed_geom_params)
415+
merge_attrs(data, ptype)
413416
},
414417

415418
compute_position = function(self, data, layout) {
416419
if (empty(data)) return(data_frame0())
417-
420+
ptype <- vec_ptype(data)
418421
data <- self$position$use_defaults(data, self$aes_params)
419422
params <- self$position$setup_params(data)
420423
data <- self$position$setup_data(data, params)
421-
422-
self$position$compute_layer(data, params, layout)
424+
data <- self$position$compute_layer(data, params, layout)
425+
merge_attrs(data, ptype)
423426
},
424427

425428
compute_geom_2 = function(self, data, params = self$aes_params, theme = NULL, ...) {
@@ -484,6 +487,10 @@ set_draw_key <- function(geom, draw_key = NULL) {
484487
}
485488

486489
cleanup_mismatched_data <- function(data, n, fun) {
490+
if (vec_duplicate_any(names(data))) {
491+
data <- data[unique0(names(data))]
492+
}
493+
487494
failed <- !lengths(data) %in% c(0, 1, n)
488495
if (!any(failed)) {
489496
return(data)

R/position-nudge.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
#' ggplot(df, aes(x, y)) +
2828
#' geom_point() +
2929
#' geom_text(aes(label = y), nudge_y = -0.1)
30+
#'
31+
#' # For each text individually
32+
#' ggplot(df, aes(x, y)) +
33+
#' geom_point() +
34+
#' geom_text(aes(label = y, nudge_y = c(-0.1, 0.1, -0.1, 0.1)))
3035
position_nudge <- function(x = NULL, y = NULL) {
3136
ggproto(NULL, PositionNudge,
3237
x = x,

R/save.R

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,18 @@ ggsave <- function(filename, plot = get_last_plot(),
101101
dev <- validate_device(device, filename, dpi = dpi)
102102
dim <- plot_dim(c(width, height), scale = scale, units = units,
103103
limitsize = limitsize, dpi = dpi)
104+
bg <- get_plot_background(plot, bg)
104105

105-
if (is_null(bg)) {
106-
bg <- calc_element("plot.background", plot_theme(plot))$fill %||% "transparent"
107-
}
108106
old_dev <- grDevices::dev.cur()
109107
dev(filename = filename, width = dim[1], height = dim[2], bg = bg, ...)
110108
on.exit(utils::capture.output({
111109
grDevices::dev.off()
112110
if (old_dev > 1) grDevices::dev.set(old_dev) # restore old device unless null device
113111
}))
114-
grid.draw(plot)
112+
if (!is_bare_list(plot)) {
113+
plot <- list(plot)
114+
}
115+
lapply(plot, grid.draw)
115116

116117
invisible(filename)
117118
}
@@ -235,6 +236,17 @@ plot_dim <- function(dim = c(NA, NA), scale = 1, units = "in",
235236
dim
236237
}
237238

239+
get_plot_background <- function(plot, bg = NULL, default = "transparent") {
240+
if (!is.null(bg)) {
241+
return(bg)
242+
}
243+
plot <- if (is_bare_list(plot)) plot[[1]] else plot
244+
if (!is.ggplot(plot)) {
245+
return(default)
246+
}
247+
calc_element("plot.background", plot_theme(plot))$fill %||% default
248+
}
249+
238250
validate_device <- function(device, filename = NULL, dpi = 300, call = caller_env()) {
239251
force(filename)
240252
force(dpi)

R/scale-date.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ ScaleContinuousDatetime <- ggproto("ScaleContinuousDatetime", ScaleContinuous,
394394
i = "The value was converted to {obj_type_friendly(x)}."
395395
), call = self$call)
396396
}
397+
if (inherits(x, "Date")) {
398+
x <- as.POSIXct(x)
399+
}
397400
ggproto_parent(ScaleContinuous, self)$transform(x)
398401
},
399402
map = function(self, x, limits = self$get_limits()) {
@@ -441,6 +444,9 @@ ScaleContinuousDate <- ggproto("ScaleContinuousDate", ScaleContinuous,
441444
i = "The value was converted to {obj_type_friendly(x)}."
442445
), call = self$call)
443446
}
447+
if (inherits(x, "POSIXct")) {
448+
x <- as.Date(x)
449+
}
444450
ggproto_parent(ScaleContinuous, self)$transform(x)
445451
},
446452
get_breaks = function(self, limits = self$get_limits()) {

R/scale-linewidth.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#'
33
#' `scale_linewidth` scales the width of lines and polygon strokes. Due to
44
#' historical reasons, it is also possible to control this with the `size`
5-
#' aesthetic, but using `linewidth` is encourage to clearly differentiate area
5+
#' aesthetic, but using `linewidth` is encouraged to clearly differentiate area
66
#' aesthetics from stroke width aesthetics.
77
#'
88
#' @name scale_linewidth

0 commit comments

Comments
 (0)