File: theme-current.R

package info (click to toggle)
r-cran-ggplot2 4.0.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 11,084 kB
  • sloc: sh: 15; makefile: 5
file content (144 lines) | stat: -rw-r--r-- 4,460 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#' @include theme-defaults.R
#' @include theme-elements.R
NULL

#' Get, set, and modify the active theme
#'
#' The current/active theme (see [theme()]) is automatically applied to every
#' plot you draw. Use `get_theme()` to get the current theme, and `set_theme()` to
#' completely override it. `update_theme()` and `replace_theme()` are shorthands for
#' changing individual elements.
#'
#' @section Adding on to a theme:
#'
#'   `+` and `%+replace%` can be used to modify elements in themes.
#'
#'   `+` updates the elements of e1 that differ from elements specified (not
#'   `NULL`) in e2. Thus this operator can be used to incrementally add or modify
#'   attributes of a ggplot theme.
#'
#'   In contrast, `%+replace%` replaces the entire element; any element of a
#'   theme not specified in e2 will not be present in the resulting theme (i.e.
#'   `NULL`). Thus this operator can be used to overwrite an entire theme.
#'
#'   `update_theme()` uses the `+` operator, so that any unspecified values in the
#'   theme element will default to the values they are set in the theme.
#'   `replace_theme()` uses `%+replace%` to completely replace the element, so any
#'   unspecified values will overwrite the current value in the theme with
#'   `NULL`.
#'
#'   In summary, the main differences between `set_theme()`, `update_theme()`,
#'   and `replace_theme()` are:
#'   * `set_theme()` completely overrides the current theme.
#'   * `update_theme()` modifies a particular element of the current theme
#'   using the `+` operator.
#'   * `replace_theme()` modifies a particular element of the current theme
#'   using the `%+replace%` operator.
#'
#' @param ... named list of theme settings
#' @param e1,e2 Theme and element to combine
#' @return `set_theme()`, `update_theme()`, and `replace_theme()`
#'   invisibly return the previous theme so you can easily save it, then
#'   later restore it.
#' @seealso [add_gg()]
#' @export
#' @examples
#' p <- ggplot(mtcars, aes(mpg, wt)) +
#'   geom_point()
#' p
#'
#' # Use set_theme() to completely override the current theme.
#' # update_theme() and replace_theme() are similar except they
#' # apply directly to the current/active theme.
#' # update_theme() modifies a particular element of the current theme.
#' # Here we have the old theme so we can later restore it.
#' # Note that the theme is applied when the plot is drawn, not
#' # when it is created.
#' old <- set_theme(theme_bw())
#' p
#'
#' set_theme(old)
#' update_theme(panel.grid.minor = element_line(colour = "red"))
#' p
#'
#' set_theme(old)
#' replace_theme(panel.grid.minor = element_line(colour = "red"))
#' p
#'
#' set_theme(old)
#' p
#'
#'
#' # Modifying theme objects -----------------------------------------
#' # You can use + and %+replace% to modify a theme object.
#' # They differ in how they deal with missing arguments in
#' # the theme elements.
#'
#' add_el <- theme_grey() +
#'   theme(text = element_text(family = "Times"))
#' add_el$text
#'
#' rep_el <- theme_grey() %+replace%
#'   theme(text = element_text(family = "Times"))
#' rep_el$text
#'
get_theme <- function() {
  ggplot_global$theme_current
}

#' @export
#' @rdname get_theme
theme_get <- get_theme

#' @rdname get_theme
#' @param new new theme (a list of theme elements). Sets theme to the default ([theme_grey()]) if `new` isn't supplied.
#' @export
set_theme <- function(new = NULL) {
  new <- new %||% ggplot_global$theme_default
  check_object(new, is_theme, "a {.cls theme} object")
  old <- ggplot_global$theme_current
  ggplot_global$theme_current <- new
  invisible(old)
}

#' @export
#' @rdname get_theme
theme_set <- set_theme

#' @rdname get_theme
#' @export
update_theme <- function(...) {
  set_theme(get_theme() + theme(...))
}

#' @export
#' @rdname get_theme
theme_update <- update_theme

#' @rdname get_theme
#' @export
replace_theme <- function(...) {
  set_theme(get_theme() %+replace% theme(...))
}

#' @export
#' @rdname get_theme
theme_replace <- replace_theme

#' @rdname get_theme
#' @export
"%+replace%" <- function(e1, e2) {
  if (!is_theme(e1) || !is_theme(e2)) {
    cli::cli_abort("{.code %+replace%} requires two theme objects")
  }

  # Can't use modifyList here since it works recursively and drops NULLs
  e1[names(e2)] <- e2

  # comment by @clauswilke:
  # `complete` and `validate` are currently ignored,
  # which means they are taken from e1. Is this correct?
  # I'm not sure how `%+replace%` should handle them.

  e1
}