Skip to content

Commit a420264

Browse files
authored
Update to update_*_defaults() (reviving #5781) (#5846)
* Update to `update_*_defaults()` (#5781) * unify updating mechanism * add tests * redocument * add news bullet * add review suggestion * move news bullet
1 parent 073958d commit a420264

File tree

4 files changed

+63
-23
lines changed

4 files changed

+63
-23
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# ggplot2 (development version)
22

3+
* `update_geom_defaults()` and `update_stat_defaults()` have a reset mechanism
4+
when using `new = NULL` and invisible return the previous defaults (#4993).
35
* Fixed regression in axes where `breaks = NULL` caused the axes to disappear
46
instead of just rendering the axis line (@teunbrand, #5816).
57
* `geom_point()` can be dodged vertically by using

R/geom-defaults.R

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#' @param stat,geom Name of geom/stat to modify (like `"point"` or
44
#' `"bin"`), or a Geom/Stat object (like `GeomPoint` or
55
#' `StatBin`).
6-
#' @param new Named list of aesthetics.
6+
#' @param new One of the following:
7+
#' * A named list of aesthetics to serve as new defaults.
8+
#' * `NULL` to reset the defaults.
79
#' @keywords internal
810
#' @export
911
#' @examples
@@ -16,7 +18,7 @@
1618
#' ggplot(mtcars, aes(mpg, wt)) + geom_point()
1719
#'
1820
#' # reset default
19-
#' update_geom_defaults("point", aes(color = "black"))
21+
#' update_geom_defaults("point", NULL)
2022
#'
2123
#'
2224
#' # updating a stat's default aesthetic settings
@@ -29,27 +31,45 @@
2931
#' geom_function(fun = dnorm, color = "red")
3032
#'
3133
#' # reset default
32-
#' update_stat_defaults("bin", aes(y = after_stat(count)))
34+
#' update_stat_defaults("bin", NULL)
3335
#'
3436
#' @rdname update_defaults
3537
update_geom_defaults <- function(geom, new) {
36-
g <- check_subclass(geom, "Geom", env = parent.frame())
37-
old <- g$default_aes
38-
new <- rename_aes(new)
39-
new_names_order <- unique(c(names(old), names(new)))
40-
new <- defaults(new, old)[new_names_order]
41-
g$default_aes[names(new)] <- new
42-
invisible()
38+
update_defaults(geom, "Geom", new, env = parent.frame())
4339
}
4440

4541
#' @rdname update_defaults
4642
#' @export
4743
update_stat_defaults <- function(stat, new) {
48-
g <- check_subclass(stat, "Stat", env = parent.frame())
49-
old <- g$default_aes
50-
new <- rename_aes(new)
51-
new_names_order <- unique(c(names(old), names(new)))
52-
new <- defaults(new, old)[new_names_order]
53-
g$default_aes[names(new)] <- new
54-
invisible()
44+
update_defaults(stat, "Stat", new, env = parent.frame())
45+
}
46+
47+
cache_defaults <- new_environment()
48+
49+
update_defaults <- function(name, subclass, new, env = parent.frame()) {
50+
obj <- check_subclass(name, subclass, env = env)
51+
index <- snake_class(obj)
52+
53+
if (is.null(new)) { # Reset from cache
54+
55+
old <- cache_defaults[[index]]
56+
if (!is.null(old)) {
57+
new <- update_defaults(name, subclass, new = old, env = env)
58+
}
59+
invisible(new)
60+
61+
} else { # Update default aesthetics
62+
63+
old <- obj$default_aes
64+
# Only update cache the first time defaults are changed
65+
if (!exists(index, envir = cache_defaults)) {
66+
cache_defaults[[index]] <- old
67+
}
68+
new <- rename_aes(new)
69+
name_order <- unique(c(names(old), names(new)))
70+
new <- defaults(new, old)[name_order]
71+
obj$default_aes[names(new)] <- new
72+
invisible(old)
73+
74+
}
5575
}

man/update_defaults.Rd

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-geom-.R

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,21 @@ test_that("aesthetic checking in geom throws correct errors", {
66
expect_snapshot_error(check_aesthetics(aes, 4))
77
})
88

9-
9+
test_that("geom defaults can be set and reset", {
10+
l <- geom_point()
11+
test <- l$geom$use_defaults(data_frame0())
12+
expect_equal(test$colour, "black")
13+
14+
inv <- update_geom_defaults("point", list(colour = "red"))
15+
test <- l$geom$use_defaults(data_frame0())
16+
expect_equal(test$colour, "red")
17+
expect_equal(inv$colour, "black")
18+
19+
inv <- update_geom_defaults("point", NULL)
20+
test <- l$geom$use_defaults(data_frame0())
21+
expect_equal(test$colour, "black")
22+
expect_equal(inv$colour, "red")
23+
})
1024

1125
test_that("updating geom aesthetic defaults preserves class and order", {
1226

@@ -23,7 +37,7 @@ test_that("updating geom aesthetic defaults preserves class and order", {
2337

2438
expect_equal(updated_defaults, intended_defaults)
2539

26-
update_geom_defaults("point", original_defaults)
40+
update_geom_defaults("point", NULL)
2741

2842
})
2943

@@ -46,6 +60,6 @@ test_that("updating stat aesthetic defaults preserves class and order", {
4660

4761
expect_equal(updated_defaults, intended_defaults)
4862

49-
update_stat_defaults("bin", original_defaults)
63+
update_stat_defaults("bin", NULL)
5064

5165
})

0 commit comments

Comments
 (0)