Skip to content

Commit b2af2fb

Browse files
authored
Merge branch 'main' into mgcv_suggests
2 parents afa61f7 + cd9410c commit b2af2fb

File tree

15 files changed

+207
-81
lines changed

15 files changed

+207
-81
lines changed

DESCRIPTION

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ Depends:
3333
R (>= 3.5)
3434
Imports:
3535
cli,
36-
glue,
3736
grDevices,
3837
grid,
3938
gtable (>= 0.1.1),

NAMESPACE

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,6 @@ import(gtable)
727727
import(rlang)
728728
import(scales)
729729
import(vctrs)
730-
importFrom(glue,glue)
731-
importFrom(glue,glue_collapse)
732730
importFrom(grid,arrow)
733731
importFrom(grid,unit)
734732
importFrom(lifecycle,deprecated)

NEWS.md

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

33
* Moved {mgcv} from Imports to Suggests (@teunbrand, #5986)
4+
* ggplot2 no longer imports {glue} (@teunbrand, #5986).
5+
* `geom_rect()` can now derive the required corners positions from `x`/`width`
6+
or `y`/`height` parameterisation (@teunbrand, #5861).
47
* All position scales now use the same definition of `x` and `y` aesthetics.
58
This lets uncommon aesthetics like `xintercept` expand scales as usual.
69
(#3342, #4966, @teunbrand)

R/aes-evaluation.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ is_calculated <- function(x, warn = FALSE) {
231231
} else if (is.symbol(x)) {
232232
res <- is_dotted_var(as.character(x))
233233
if (res && warn) {
234-
what <- I(glue("The dot-dot notation (`{x}`)"))
234+
what <- I(paste0("The dot-dot notation (`", x, "`)"))
235235
var <- gsub(match_calculated_aes, "\\1", as.character(x))
236-
with <- I(glue("`after_stat({var})`"))
236+
with <- I(paste0("`after_stat(", var, ")`"))
237237
deprecate_warn0("3.4.0", what, with, id = "ggplot-warn-aes-dot-dot")
238238
}
239239
res
@@ -242,9 +242,9 @@ is_calculated <- function(x, warn = FALSE) {
242242
} else if (is.call(x)) {
243243
if (identical(x[[1]], quote(stat))) {
244244
if (warn) {
245-
what <- I(glue("`{expr_deparse(x)}`"))
245+
what <- I(paste0("`", expr_deparse(x), "`"))
246246
x[[1]] <- quote(after_stat)
247-
with <- I(glue("`{expr_deparse(x)}`"))
247+
with <- I(paste0("`", expr_deparse(x), "`"))
248248
deprecate_warn0("3.4.0", what, with, id = "ggplot-warn-aes-stat")
249249
}
250250
TRUE

R/fortify.R

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,21 @@ validate_as_data_frame <- function(data) {
7474

7575
#' @export
7676
fortify.default <- function(model, data, ...) {
77-
msg0 <- paste0(
78-
"{{.arg data}} must be a {{.cls data.frame}}, ",
79-
"or an object coercible by {{.fn fortify}}, or a valid ",
80-
"{{.cls data.frame}}-like object coercible by {{.fn as.data.frame}}"
77+
msg <- paste0(
78+
"{.arg data} must be a {.cls data.frame}, ",
79+
"or an object coercible by {.fn fortify}, or a valid ",
80+
"{.cls data.frame}-like object coercible by {.fn as.data.frame}"
8181
)
8282
if (inherits(model, "uneval")) {
8383
msg <- c(
84-
glue(msg0, ", not {obj_type_friendly(model)}."),
84+
paste0(msg, ", not ", obj_type_friendly(model), "."),
8585
"i" = "Did you accidentally pass {.fn aes} to the {.arg data} argument?"
8686
)
8787
cli::cli_abort(msg)
8888
}
89-
msg0 <- paste0(msg0, ". ")
89+
msg <- paste0(msg, ".")
9090
try_fetch(
9191
validate_as_data_frame(model),
92-
error = function(cnd) cli::cli_abort(glue(msg0), parent = cnd)
92+
error = function(cnd) cli::cli_abort(msg, parent = cnd)
9393
)
9494
}

R/geom-rect.R

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,39 @@ GeomRect <- ggproto("GeomRect", Geom,
3131
default_aes = aes(colour = NA, fill = "grey35", linewidth = 0.5, linetype = 1,
3232
alpha = NA),
3333

34-
required_aes = c("xmin", "xmax", "ymin", "ymax"),
34+
required_aes = c("x|width|xmin|xmax", "y|height|ymin|ymax"),
35+
36+
setup_data = function(self, data, params) {
37+
if (all(c("xmin", "xmax", "ymin", "ymax") %in% names(data))) {
38+
return(data)
39+
}
40+
41+
# Fill in missing aesthetics from parameters
42+
required <- strsplit(self$required_aes, "|", fixed = TRUE)
43+
missing <- setdiff(unlist(required), names(data))
44+
default <- params[intersect(missing, names(params))]
45+
data[names(default)] <- default
46+
47+
if (is.null(data$xmin) || is.null(data$xmax)) {
48+
x <- resolve_rect(
49+
data[["xmin"]], data[["xmax"]],
50+
data[["x"]], data[["width"]],
51+
fun = snake_class(self), type = "x"
52+
)
53+
i <- lengths(x) > 1
54+
data[c("xmin", "xmax")[i]] <- x[i]
55+
}
56+
if (is.null(data$ymin) || is.null(data$ymax)) {
57+
y <- resolve_rect(
58+
data[["ymin"]], data[["ymax"]],
59+
data[["y"]], data[["height"]],
60+
fun = snake_class(self), type = "y"
61+
)
62+
i <- lengths(y) > 1
63+
data[c("ymin", "ymax")[i]] <- y[i]
64+
}
65+
data
66+
},
3567

3668
draw_panel = function(self, data, panel_params, coord, lineend = "butt", linejoin = "mitre") {
3769
data <- check_linewidth(data, snake_class(self))
@@ -73,3 +105,41 @@ GeomRect <- ggproto("GeomRect", Geom,
73105

74106
rename_size = TRUE
75107
)
108+
109+
resolve_rect <- function(min = NULL, max = NULL, center = NULL, length = NULL,
110+
fun, type) {
111+
absent <- c(is.null(min), is.null(max), is.null(center), is.null(length))
112+
if (sum(absent) > 2) {
113+
missing <- switch(
114+
type,
115+
x = c("xmin", "xmax", "x", "width"),
116+
y = c("ymin", "ymax", "y", "height")
117+
)
118+
cli::cli_abort(c(
119+
"{.fn {fun}} requires two of the following aesthetics: \\
120+
{.or {.field {missing}}}.",
121+
i = "Currently, {.field {missing[!absent]}} is present."
122+
))
123+
}
124+
125+
if (absent[1] && absent[2]) {
126+
min <- center - 0.5 * length
127+
max <- center + 0.5 * length
128+
return(list(min = min, max = max))
129+
}
130+
if (absent[1]) {
131+
if (is.null(center)) {
132+
min <- max - length
133+
} else {
134+
min <- max - 2 * (max - center)
135+
}
136+
}
137+
if (absent[2]) {
138+
if (is.null(center)) {
139+
max <- min + length
140+
} else {
141+
max <- min + 2 * (center - min)
142+
}
143+
}
144+
list(min = min, max = max)
145+
}

R/geom-tile.R

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
#' Rectangles
22
#'
33
#' `geom_rect()` and `geom_tile()` do the same thing, but are
4-
#' parameterised differently: `geom_rect()` uses the locations of the four
5-
#' corners (`xmin`, `xmax`, `ymin` and `ymax`), while
6-
#' `geom_tile()` uses the center of the tile and its size (`x`,
7-
#' `y`, `width`, `height`). `geom_raster()` is a high
8-
#' performance special case for when all the tiles are the same size, and no
9-
#' pattern fills are applied.
4+
#' parameterised differently: `geom_tile()` uses the center of the tile and its
5+
#' size (`x`, `y`, `width`, `height`), while `geom_rect()` can use those or the
6+
#' locations of the corners (`xmin`, `xmax`, `ymin` and `ymax`).
7+
#' `geom_raster()` is a high performance special case for when all the tiles
8+
#' are the same size, and no pattern fills are applied.
109
#'
11-
#' @eval rd_aesthetics("geom", "tile", "Note that `geom_raster()` ignores `colour`.")
10+
#' @eval rd_aesthetics(
11+
#' "geom", "rect",
12+
#' "`geom_tile()` understands only the `x`/`width` and `y`/`height` combinations.
13+
#' Note that `geom_raster()` ignores `colour`."
14+
#' )
1215
#' @inheritParams layer
1316
#' @inheritParams geom_point
1417
#' @inheritParams geom_segment
1518
#' @export
1619
#'
1720
#' @details
18-
#' `geom_rect()` and `geom_tile()`'s respond differently to scale
19-
#' transformations due to their parameterisation. In `geom_rect()`, the scale
20-
#' transformation is applied to the corners of the rectangles. In `geom_tile()`,
21-
#' the transformation is applied only to the centres and its size is determined
22-
#' after transformation.
21+
#' Please note that the `width` and `height` aesthetics are not true position
22+
#' aesthetics and therefore are not subject to scale transformation. It is
23+
#' only after transformation that these aesthetics are applied.
2324
#'
2425
#' @examples
2526
#' # The most common use for rectangles is to draw a surface. You always want

R/ggplot2-package.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
## usethis namespace: start
55
#' @import scales grid gtable rlang vctrs
6-
#' @importFrom glue glue glue_collapse
76
#' @importFrom lifecycle deprecated
87
#' @importFrom stats setNames
98
#' @importFrom utils head tail

R/labels.R

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -205,40 +205,36 @@ get_alt_text.gtable <- function(p, ...) {
205205
generate_alt_text <- function(p) {
206206
# Combine titles
207207
if (!is.null(p$label$title %||% p$labels$subtitle)) {
208-
title <- glue(glue_collapse(
209-
sub("\\.?$", "", c(p$labels$title, p$labels$subtitle)),
210-
last = ": "
211-
), ". ")
208+
title <- sub("\\.?$", "", c(p$labels$title, p$labels$subtitle))
209+
if (length(title) == 2) {
210+
title <- paste0(title[1], ": ", title[2])
211+
}
212+
title <- paste0(title, ". ")
212213
title <- safe_string(title)
213214
} else {
214215
title <- ""
215216
}
216217

217218

218219
# Get axes descriptions
219-
axes <- glue(" showing ", glue_collapse(
220-
c(scale_description(p, "x"), scale_description(p, "y")),
221-
last = " and "
222-
))
220+
axes <- paste0(" showing ", scale_description(p, "x"), " and ", scale_description(p, "y"))
223221
axes <- safe_string(axes)
224222

225223
# Get layer types
226224
layers <- vapply(p$layers, function(l) snake_class(l$geom), character(1))
227225
layers <- sub("_", " ", sub("^geom_", "", unique0(layers)))
228-
layers <- glue(
229-
" using ",
230-
if (length(layers) == 1) "a " else "",
231-
glue_collapse(layers, sep = ", ", last = " and "),
232-
" layer",
233-
if (length(layers) == 1) "" else "s"
234-
)
226+
if (length(layers) == 1) {
227+
layers <- paste0(" using a ", layers, " layer")
228+
} else {
229+
layers <- paste0(" using ", oxford_comma(layers), " layers")
230+
}
235231
layers <- safe_string(layers)
236232

237233
# Combine
238-
alt <- glue_collapse(
239-
c(glue("{title}A plot{axes}{layers}"), p$labels$alt_insight),
240-
last = ". "
241-
)
234+
alt <- paste0(title, "A plot", axes, layers, ".")
235+
if (!is.null(p$labels$alt_insight)) {
236+
alt <- paste0(alt, " ", p$labels$alt_insight)
237+
}
242238
as.character(alt)
243239
}
244240
safe_string <- function(string) {
@@ -258,5 +254,5 @@ scale_description <- function(p, name) {
258254
if (is.null(lab)) {
259255
return(NULL)
260256
}
261-
glue("{lab} on {type} {name}-axis")
257+
paste0(lab, " on ", type, " ", name, "-axis")
262258
}

R/utilities-help.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ rd_aesthetics <- function(type, name, extra_note = NULL) {
2323

2424
rd_aesthetics_item <- function(x) {
2525
req <- x$required_aes
26-
req <- sub("|", "} \\emph{or} \\code{", req, fixed = TRUE)
26+
req <- gsub("|", "} \\emph{or} \\code{", req, fixed = TRUE)
2727
req_aes <- unlist(strsplit(x$required_aes, "|", fixed = TRUE))
2828
optional_aes <- setdiff(x$aesthetics(), req_aes)
2929
all <- union(req, sort(optional_aes))

0 commit comments

Comments
 (0)