Skip to content

Commit 171664b

Browse files
authored
Label accessor (#6078)
* guides merge aesthetics * add getter for completed plot labels * incorporate getter in tests * document
1 parent 7f6d5bf commit 171664b

File tree

7 files changed

+70
-46
lines changed

7 files changed

+70
-46
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ export(get_alt_text)
426426
export(get_element_tree)
427427
export(get_geom_defaults)
428428
export(get_guide_data)
429+
export(get_labs)
429430
export(get_last_plot)
430431
export(get_layer_data)
431432
export(get_layer_grob)

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+
* New `get_labs()` function for retrieving completed plot labels
4+
(@teunbrand, #6008).
35
* Built-in `theme_*()` functions now have `ink` and `paper` arguments to control
46
foreground and background colours respectively (@teunbrand)
57
* The `summary()` method for ggplots is now more terse about facets

R/guide-colorbar.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ GuideColourbar <- ggproto(
273273
merge = function(self, params, new_guide, new_params) {
274274
new_params$key$.label <- new_params$key$.value <- NULL
275275
params$key <- vec_cbind(params$key, new_params$key)
276+
params$aesthetic <- union(params$aesthetic, new_params$aesthetic)
276277
return(list(guide = self, params = params))
277278
},
278279

R/guide-legend.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ GuideLegend <- ggproto(
204204
cli::cli_warn("Duplicated {.arg override.aes} is ignored.")
205205
}
206206
params$override.aes <- params$override.aes[!duplicated(nms)]
207+
params$aesthetic <- union(params$aesthetic, new_params$aesthetic)
207208

208209
list(guide = self, params = params)
209210
},

R/labels.R

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,39 @@ ggtitle <- function(label, subtitle = waiver()) {
179179
labs(title = label, subtitle = subtitle)
180180
}
181181

182+
#' @rdname labs
183+
#' @export
184+
#' @param plot A ggplot object
185+
#' @description
186+
#' `get_labs()` retrieves completed labels from a plot.
187+
get_labs <- function(plot = get_last_plot()) {
188+
plot <- ggplot_build(plot)
189+
190+
labs <- plot$plot$labels
191+
192+
xy_labs <- rename(
193+
c(x = plot$layout$resolve_label(plot$layout$panel_scales_x[[1]], labs),
194+
y = plot$layout$resolve_label(plot$layout$panel_scales_y[[1]], labs)),
195+
c(x.primary = "x", x.secondary = "x.sec",
196+
y.primary = "y", y.secondary = "y.sec")
197+
)
198+
199+
labs <- defaults(xy_labs, labs)
200+
201+
guides <- plot$plot$guides
202+
if (length(guides$aesthetics) == 0) {
203+
return(labs)
204+
}
205+
206+
for (aes in guides$aesthetics) {
207+
param <- guides$get_params(aes)
208+
aes <- param$aesthetic # Can have length > 1 when guide was merged
209+
title <- vec_set_names(rep(list(param$title), length(aes)), aes)
210+
labs <- defaults(title, labs)
211+
}
212+
labs
213+
}
214+
182215
#' Extract alt text from a plot
183216
#'
184217
#' This function returns a text that can be used as alt-text in webpages etc.

man/labs.Rd

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

tests/testthat/test-labels.R

Lines changed: 25 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,22 @@ test_that("setting guide labels works", {
5252
test_that("Labels from default stat mapping are overwritten by default labels", {
5353
p <- ggplot(mpg, aes(displ, hwy)) +
5454
geom_density2d()
55-
labels <- ggplot_build(p)$plot$labels
5655

56+
labels <- get_labs(p)
5757
expect_equal(labels$colour[1], "colour")
5858
expect_true(attr(labels$colour, "fallback"))
5959

6060
p <- p + geom_smooth(aes(color = drv), method = "lm", formula = y ~ x)
61-
labels <- ggplot_build(p)$plot$labels
62-
63-
expect_equal(labels$colour, "drv")
61+
expect_equal(get_labs(p)$colour, "drv")
6462
})
6563

6664
test_that("Labels can be extracted from attributes", {
6765
df <- mtcars
6866
attr(df$mpg, "label") <- "Miles per gallon"
6967

7068
p <- ggplot(df, aes(mpg, disp)) + geom_point()
71-
labels <- ggplot_build(p)$plot$labels
7269

70+
labels <- get_labs(p)
7371
expect_equal(labels$x, "Miles per gallon")
7472
expect_equal(labels$y, "disp")
7573
})
@@ -79,14 +77,10 @@ test_that("Labels from static aesthetics are ignored (#6003)", {
7977
df <- data.frame(x = 1, y = 1, f = 1)
8078

8179
p <- ggplot(df, aes(x, y, colour = f)) + geom_point()
82-
labels <- ggplot_build(p)$plot$labels
83-
84-
expect_equal(labels$colour, "f")
80+
expect_equal(get_labs(p)$colour, "f")
8581

8682
p <- ggplot(df, aes(x, y, colour = f)) + geom_point(colour = "blue")
87-
labels <- ggplot_build(p)$plot$labels
88-
89-
expect_null(labels$colour)
83+
expect_null(get_labs(p)$colour)
9084
})
9185

9286
test_that("alt text is returned", {
@@ -140,24 +134,25 @@ test_that("position axis label hierarchy works as intended", {
140134
geom_point(size = 5)
141135

142136
p <- ggplot_build(p)
137+
resolve_label <- function(x) p$layout$resolve_label(x, p$plot$labels)
143138

144139
# In absence of explicit title, get title from mapping
145140
expect_identical(
146-
p$layout$resolve_label(p$layout$panel_scales_x[[1]], p$plot$labels),
141+
resolve_label(p$layout$panel_scales_x[[1]]),
147142
list(secondary = NULL, primary = "foo")
148143
)
149144
expect_identical(
150-
p$layout$resolve_label(p$layout$panel_scales_y[[1]], p$plot$labels),
145+
resolve_label(p$layout$panel_scales_y[[1]]),
151146
list(primary = "bar", secondary = NULL)
152147
)
153148

154149
# Scale name overrules mapping label
155150
expect_identical(
156-
p$layout$resolve_label(scale_x_continuous("Baz"), p$plot$labels),
151+
resolve_label(scale_x_continuous("Baz")),
157152
list(secondary = NULL, primary = "Baz")
158153
)
159154
expect_identical(
160-
p$layout$resolve_label(scale_y_continuous("Qux"), p$plot$labels),
155+
resolve_label(scale_y_continuous("Qux")),
161156
list(primary = "Qux", secondary = NULL)
162157
)
163158

@@ -167,23 +162,23 @@ test_that("position axis label hierarchy works as intended", {
167162
p$plot$layers
168163
)
169164
expect_identical(
170-
p$layout$resolve_label(scale_x_continuous("Baz"), p$plot$labels),
165+
resolve_label(scale_x_continuous("Baz")),
171166
list(secondary = NULL, primary = "quuX")
172167
)
173168
expect_identical(
174-
p$layout$resolve_label(scale_y_continuous("Qux"), p$plot$labels),
169+
resolve_label(scale_y_continuous("Qux")),
175170
list(primary = "corgE", secondary = NULL)
176171
)
177172

178173
# Secondary axis names work
179174
xsec <- scale_x_continuous("Baz", sec.axis = dup_axis(name = "grault"))
180175
expect_identical(
181-
p$layout$resolve_label(xsec, p$plot$labels),
176+
resolve_label(xsec),
182177
list(secondary = "grault", primary = "quuX")
183178
)
184179
ysec <- scale_y_continuous("Qux", sec.axis = dup_axis(name = "garply"))
185180
expect_identical(
186-
p$layout$resolve_label(ysec, p$plot$labels),
181+
resolve_label(ysec),
187182
list(primary = "corgE", secondary = "garply")
188183
)
189184

@@ -194,12 +189,12 @@ test_that("position axis label hierarchy works as intended", {
194189
p$plot$layers
195190
)
196191
expect_identical(
197-
p$layout$resolve_label(xsec, p$plot$labels),
192+
resolve_label(xsec),
198193
list(secondary = "waldo", primary = "quuX")
199194
)
200195
ysec <- scale_y_continuous("Qux", sec.axis = dup_axis(name = "garply"))
201196
expect_identical(
202-
p$layout$resolve_label(ysec, p$plot$labels),
197+
resolve_label(ysec),
203198
list(primary = "corgE", secondary = "fred")
204199
)
205200
})
@@ -220,31 +215,20 @@ test_that("moving guide positions lets titles follow", {
220215
),
221216
p$plot$layers
222217
)
223-
expect_identical(
224-
p$layout$resolve_label(p$layout$panel_scales_x[[1]], p$plot$labels),
225-
list(secondary = NULL, primary = "baz")
226-
)
227-
expect_identical(
228-
p$layout$resolve_label(p$layout$panel_scales_y[[1]], p$plot$labels),
229-
list(primary = "qux", secondary = NULL)
230-
)
218+
labs <- get_labs(p)
219+
expect <- list(x = "baz", x.sec = NULL, y = "qux", y.sec = NULL)
220+
expect_identical(labs[names(expect)], expect)
231221

232-
# Guides at secondary positions (changes order of primary/secondary)
222+
# Guides at secondary positions
233223
p$layout$setup_panel_guides(
234224
guides_list(
235225
list(x = guide_axis("baz", position = "top"),
236226
y = guide_axis("qux", position = "right"))
237227
),
238228
p$plot$layers
239229
)
240-
expect_identical(
241-
p$layout$resolve_label(p$layout$panel_scales_x[[1]], p$plot$labels),
242-
list(primary = "baz", secondary = NULL)
243-
)
244-
expect_identical(
245-
p$layout$resolve_label(p$layout$panel_scales_y[[1]], p$plot$labels),
246-
list(secondary = NULL, primary = "qux")
247-
)
230+
labs <- get_labs(p)
231+
expect_identical(labs[names(expect)], expect)
248232

249233
# Primary guides at secondary positions with
250234
# secondary guides at primary positions
@@ -257,14 +241,9 @@ test_that("moving guide positions lets titles follow", {
257241
),
258242
p$plot$layers
259243
)
260-
expect_identical(
261-
p$layout$resolve_label(p$layout$panel_scales_x[[1]], p$plot$labels),
262-
list(primary = "baz", secondary = "quux")
263-
)
264-
expect_identical(
265-
p$layout$resolve_label(p$layout$panel_scales_y[[1]], p$plot$labels),
266-
list(secondary = "corge", primary = "qux")
267-
)
244+
labs <- get_labs(p)
245+
expect[c("x.sec", "y.sec")] <- list("quux", "corge")
246+
expect_identical(labs[names(expect)], expect)
268247
})
269248

270249
# Visual tests ------------------------------------------------------------

0 commit comments

Comments
 (0)