|
| 1 | +#' @include plot.R |
| 2 | +NULL |
| 3 | + |
1 | 4 | #' Add components to a plot
|
2 | 5 | #'
|
3 | 6 | #' `+` is the key to constructing sophisticated ggplot2 graphics. It
|
|
52 | 55 | e2name <- deparse(substitute(e2))
|
53 | 56 |
|
54 | 57 | if (is.theme(e1)) add_theme(e1, e2, e2name)
|
55 |
| - else if (is.ggplot(e1)) add_ggplot(e1, e2, e2name) |
56 | 58 | else if (is.ggproto(e1)) {
|
57 | 59 | cli::cli_abort(c(
|
58 | 60 | "Cannot add {.cls ggproto} objects together.",
|
|
61 | 63 | }
|
62 | 64 | }
|
63 | 65 |
|
| 66 | +S7::method(`+`, list(class_ggplot, S7::class_any)) <- function(e1, e2) { |
| 67 | + e2name <- deparse(substitute(e2, env = caller_env(2))) |
| 68 | + add_ggplot(e1, e2, e2name) |
| 69 | +} |
| 70 | + |
64 | 71 |
|
65 | 72 | #' @rdname gg-add
|
66 | 73 | #' @export
|
67 |
| -"%+%" <- `+.gg` |
| 74 | +"%+%" <- function(e1, e2) e1 + e2 |
68 | 75 |
|
69 | 76 | add_ggplot <- function(p, object, objectname) {
|
70 | 77 | if (is.null(object)) return(p)
|
@@ -110,88 +117,88 @@ add_ggplot <- function(p, object, objectname) {
|
110 | 117 | #'
|
111 | 118 | #' # clean-up
|
112 | 119 | #' rm(ggplot_add.element_text)
|
113 |
| -ggplot_add <- function(object, plot, object_name) { |
114 |
| - UseMethod("ggplot_add") |
115 |
| -} |
116 |
| -#' @export |
117 |
| -ggplot_add.default <- function(object, plot, object_name) { |
118 |
| - cli::cli_abort("Can't add {.var {object_name}} to a {.cls ggplot} object.") |
119 |
| -} |
120 |
| -#' @export |
121 |
| -ggplot_add.NULL <- function(object, plot, object_name) { |
122 |
| - plot |
123 |
| -} |
124 |
| -#' @export |
125 |
| -ggplot_add.data.frame <- function(object, plot, object_name) { |
126 |
| - plot@data <- object |
127 |
| - plot |
128 |
| -} |
129 |
| -#' @export |
130 |
| -ggplot_add.function <- function(object, plot, object_name) { |
131 |
| - cli::cli_abort(c( |
132 |
| - "Can't add {.var {object_name}} to a {.cls ggplot} object", |
133 |
| - "i" = "Did you forget to add parentheses, as in {.fn {object_name}}?" |
134 |
| - )) |
135 |
| -} |
| 120 | +ggplot_add <- S7::new_generic("ggplot_add", c("object", "plot")) |
136 | 121 |
|
137 |
| -#' @export |
138 |
| -ggplot_add.Scale <- function(object, plot, object_name) { |
139 |
| - plot@scales$add(object) |
140 |
| - plot |
141 |
| -} |
142 |
| -S7::method(ggplot_add, labs) <- function(object, plot, object_name) { |
143 |
| - update_labels(plot, object) |
144 |
| -} |
145 |
| -#' @export |
146 |
| -ggplot_add.Guides <- function(object, plot, object_name) { |
147 |
| - if (is.guides(plot@guides)) { |
148 |
| - # We clone the guides object to prevent modify-in-place of guides |
| 122 | +S7::method(ggplot_add, list(S7::class_any, class_ggplot)) <- |
| 123 | + function(object, plot, object_name, ...) { |
| 124 | + cli::cli_abort("Can't add {.var {object_name}} to a {.cls ggplot} object.") |
| 125 | + } |
| 126 | + |
| 127 | +S7::method(ggplot_add, list(S7::class_function, class_ggplot)) <- |
| 128 | + function(object, plot, object_name, ...) { |
| 129 | + cli::cli_abort(c( |
| 130 | + "Can't add {.var {object_name}} to a {.cls ggplot} object", |
| 131 | + "i" = "Did you forget to add parentheses, as in {.fn {object_name}}?" |
| 132 | + )) |
| 133 | + } |
| 134 | + |
| 135 | +S7::method(ggplot_add, list(NULL, class_ggplot)) <- |
| 136 | + function(object, plot, ...) { plot } |
| 137 | + |
| 138 | +S7::method(ggplot_add, list(S7::class_data.frame, class_ggplot)) <- |
| 139 | + function(object, plot, ...) { S7::set_props(plot, data = object) } |
| 140 | + |
| 141 | +S7::method(ggplot_add, list(class_scale, class_ggplot)) <- |
| 142 | + function(object, plot, ...) { |
| 143 | + plot@scales$add(object) |
| 144 | + plot |
| 145 | + } |
| 146 | + |
| 147 | +S7::method(ggplot_add, list(labs, class_ggplot)) <- |
| 148 | + function(object, plot, ...) { update_labels(plot, object) } |
| 149 | + |
| 150 | +S7::method(ggplot_add, list(class_guides, class_ggplot)) <- |
| 151 | + function(object, plot, ...) { |
149 | 152 | old <- plot@guides
|
150 | 153 | new <- ggproto(NULL, old)
|
151 | 154 | new$add(object)
|
152 | 155 | plot@guides <- new
|
153 |
| - } else { |
154 |
| - plot@guides <- object |
| 156 | + plot |
155 | 157 | }
|
156 |
| - plot |
157 |
| -} |
158 |
| -S7::method(ggplot_add, mapping) <- function(object, plot, object_name) { |
159 |
| - plot@mapping <- mapping(defaults(object, plot@mapping)) |
160 |
| - plot |
161 |
| -} |
162 |
| -#' @export |
163 |
| -ggplot_add.Coord <- function(object, plot, object_name) { |
164 |
| - if (!isTRUE(plot@coordinates$default)) { |
165 |
| - cli::cli_inform("Coordinate system already present. Adding new coordinate system, which will replace the existing one.") |
| 158 | + |
| 159 | +S7::method(ggplot_add, list(mapping, class_ggplot)) <- |
| 160 | + function(object, plot, ...) { |
| 161 | + S7::set_props(plot, mapping = mapping(defaults(object, plot@mapping))) |
166 | 162 | }
|
167 | 163 |
|
168 |
| - plot@coordinates <- object |
169 |
| - plot |
170 |
| -} |
171 |
| -#' @export |
172 |
| -ggplot_add.Facet <- function(object, plot, object_name) { |
173 |
| - plot@facet <- object |
174 |
| - plot |
175 |
| -} |
176 |
| -#' @export |
177 |
| -ggplot_add.list <- function(object, plot, object_name) { |
178 |
| - for (o in object) { |
179 |
| - plot <- ggplot_add(o, plot, object_name) |
| 164 | +S7::method(ggplot_add, list(theme, class_ggplot)) <- |
| 165 | + function(object, plot, ...) { |
| 166 | + S7::set_props(plot, theme = add_theme(plot@theme, object)) |
180 | 167 | }
|
181 |
| - plot |
182 |
| -} |
183 |
| -#' @export |
184 |
| -ggplot_add.by <- function(object, plot, object_name) { |
185 |
| - ggplot_add.list(object, plot, object_name) |
186 |
| -} |
187 | 168 |
|
188 |
| -#' @export |
189 |
| -ggplot_add.Layer <- function(object, plot, object_name) { |
190 |
| - layers_names <- new_layer_names(object, names2(plot@layers)) |
191 |
| - plot@layers <- append(plot@layers, object) |
192 |
| - names(plot@layers) <- layers_names |
193 |
| - plot |
194 |
| -} |
| 169 | +S7::method(ggplot_add, list(class_coord, class_ggplot)) <- |
| 170 | + function(object, plot, ...) { |
| 171 | + if (!isTRUE(plot@coordinates$default)) { |
| 172 | + cli::cli_inform(c( |
| 173 | + "Coordinate system already present.", |
| 174 | + i = "Adding new coordinate system, which will replace the existing one." |
| 175 | + )) |
| 176 | + } |
| 177 | + S7::set_props(plot, coordinates = object) |
| 178 | + } |
| 179 | + |
| 180 | +S7::method(ggplot_add, list(class_facet, class_ggplot)) <- |
| 181 | + function(object, plot, ...) { S7::set_props(plot, facet = object) } |
| 182 | + |
| 183 | +S7::method(ggplot_add, list(class_layer, class_ggplot)) <- |
| 184 | + function(object, plot, ...) { |
| 185 | + layers_names <- new_layer_names(object, names2(plot@layers)) |
| 186 | + object <- setNames(append(plot@layers, object), layers_names) |
| 187 | + S7::set_props(plot, layers = object) |
| 188 | + } |
| 189 | + |
| 190 | +S7::method(ggplot_add, list(S7::class_list, class_ggplot)) <- |
| 191 | + function(object, plot, object_name, ...) { |
| 192 | + for (o in object) { |
| 193 | + plot <- ggplot_add(o, plot, object_name) |
| 194 | + } |
| 195 | + plot |
| 196 | + } |
| 197 | + |
| 198 | +S7::method(ggplot_add, list(S7::new_S3_class("by"), class_ggplot)) <- |
| 199 | + function(object, plot, object_name, ...) { |
| 200 | + ggplot_add(unclass(object), plot, object_name) |
| 201 | + } |
195 | 202 |
|
196 | 203 | new_layer_names <- function(layer, existing) {
|
197 | 204 |
|
|
0 commit comments