Skip to content

Commit e0bb6a3

Browse files
authored
Strip label accessor (#5924)
* new format_strip_labels method * use new method * new accessor function * add test * add news bullet
1 parent 66a4362 commit e0bb6a3

File tree

8 files changed

+127
-24
lines changed

8 files changed

+127
-24
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ export(get_last_plot)
427427
export(get_layer_data)
428428
export(get_layer_grob)
429429
export(get_panel_scales)
430+
export(get_strip_labels)
430431
export(get_theme)
431432
export(gg_dep)
432433
export(gg_par)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
are not of the correct length (#5901).
120120
* `geom_hline()` and `geom_vline()` now have `position` argument
121121
(@yutannihilation, #4285).
122+
* New function `get_strip_labels()` to retrieve facet labels (@teunbrand, #4979)
122123

123124
# ggplot2 3.5.1
124125

R/facet-.R

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ Facet <- ggproto("Facet", NULL,
257257
},
258258
vars = function() {
259259
character(0)
260+
},
261+
format_strip_labels = function(layout, params) {
262+
return()
260263
}
261264
)
262265

@@ -321,6 +324,31 @@ vars <- function(...) {
321324
quos(...)
322325
}
323326

327+
#' Accessing a plot's facet strip labels
328+
#'
329+
#' This functions retrieves labels from facet strips with the labeller applied.
330+
#'
331+
#' @param plot A ggplot or build ggplot object.
332+
#'
333+
#' @return `NULL` if there are no labels, otherwise a list of data.frames
334+
#' containing the labels.
335+
#' @export
336+
#' @keywords internal
337+
#'
338+
#' @examples
339+
#' # Basic plot
340+
#' p <- ggplot(mpg, aes(displ, hwy)) +
341+
#' geom_point()
342+
#'
343+
#' get_strip_labels(p) # empty facets
344+
#' get_strip_labels(p + facet_wrap(year ~ cyl))
345+
#' get_strip_labels(p + facet_grid(year ~ cyl))
346+
get_strip_labels <- function(plot = get_last_plot()) {
347+
plot <- ggplot_build(plot)
348+
layout <- plot$layout$layout
349+
params <- plot$layout$facet_params
350+
plot$plot$facet$format_strip_labels(layout, params)
351+
}
324352

325353
#' Is this object a faceting specification?
326354
#'
@@ -779,7 +807,7 @@ render_axes <- function(x = NULL, y = NULL, coord, theme, transpose = FALSE) {
779807
#'
780808
#' @keywords internal
781809
#' @export
782-
render_strips <- function(x = NULL, y = NULL, labeller, theme) {
810+
render_strips <- function(x = NULL, y = NULL, labeller = identity, theme) {
783811
list(
784812
x = build_strip(x, labeller, theme, TRUE),
785813
y = build_strip(y, labeller, theme, FALSE)

R/facet-grid-.R

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,16 +380,11 @@ FacetGrid <- ggproto("FacetGrid", Facet,
380380
table
381381
},
382382

383-
attach_strips = function(table, layout, params, theme) {
383+
attach_strips = function(self, table, layout, params, theme) {
384384

385-
col_vars <- unique0(layout[names(params$cols)])
386-
row_vars <- unique0(layout[names(params$rows)])
387-
attr(col_vars, "type") <- "cols"
388-
attr(row_vars, "type") <- "rows"
389-
attr(col_vars, "facet") <- "grid"
390-
attr(row_vars, "facet") <- "grid"
385+
strips <- self$format_strip_labels(layout, params)
386+
strips <- render_strips(strips$cols, strips$rows, theme = theme)
391387

392-
strips <- render_strips(col_vars, row_vars, params$labeller, theme)
393388
padding <- convertUnit(calc_element("strip.switch.pad.grid", theme), "cm")
394389

395390
switch_x <- !is.null(params$switch) && params$switch %in% c("both", "x")
@@ -432,6 +427,33 @@ FacetGrid <- ggproto("FacetGrid", Facet,
432427

433428
vars = function(self) {
434429
names(c(self$params$rows, self$params$cols))
430+
},
431+
432+
format_strip_labels = function(layout, params) {
433+
434+
labeller <- match.fun(params$labeller)
435+
436+
cols <- intersect(names(layout), names(params$cols))
437+
if (length(cols) > 0) {
438+
col_vars <- unique0(layout[cols])
439+
attr(col_vars, "type") <- "cols"
440+
attr(col_vars, "facet") <- "grid"
441+
cols <- data_frame0(!!!labeller(col_vars))
442+
} else {
443+
cols <- NULL
444+
}
445+
446+
rows <- intersect(names(layout), names(params$rows))
447+
if (length(rows) > 0) {
448+
row_vars <- unique0(layout[rows])
449+
attr(row_vars, "type") <- "rows"
450+
attr(row_vars, "facet") <- "grid"
451+
rows <- data_frame0(!!!labeller(row_vars))
452+
} else {
453+
rows <- NULL
454+
}
455+
456+
list(cols = cols, rows = rows)
435457
}
436458
)
437459

R/facet-wrap.R

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -371,22 +371,11 @@ FacetWrap <- ggproto("FacetWrap", Facet,
371371
weave_axes(table, axes, empty)
372372
},
373373

374-
attach_strips = function(table, layout, params, theme) {
374+
attach_strips = function(self, table, layout, params, theme) {
375375

376376
# Format labels
377-
if (length(params$facets) == 0) {
378-
labels <- data_frame0("(all)" = "(all)", .size = 1)
379-
} else {
380-
labels <- layout[names(params$facets)]
381-
}
382-
attr(labels, "facet") <- "wrap"
383-
384-
# Render individual strips
385-
strips <- render_strips(
386-
x = structure(labels, type = "rows"),
387-
y = structure(labels, type = "cols"),
388-
params$labeller, theme
389-
)
377+
strips <- self$format_strip_labels(layout, params)
378+
strips <- render_strips(strips$facets, strips$facets, theme = theme)
390379

391380
# Set position invariant parameters
392381
padding <- convertUnit(calc_element("strip.switch.pad.wrap", theme), "cm")
@@ -457,6 +446,22 @@ FacetWrap <- ggproto("FacetWrap", Facet,
457446
},
458447
vars = function(self) {
459448
names(self$params$facets)
449+
},
450+
451+
format_strip_labels = function(layout, params) {
452+
if (length(params$facets) == 0) {
453+
labels <- data_frame0("(all)" = "(all)", .size = 1)
454+
} else {
455+
labels <- layout[intersect(names(params$facets), names(layout))]
456+
}
457+
if (empty(labels)) {
458+
return(NULL)
459+
}
460+
attr(labels, "facet") <- "wrap"
461+
attr(labels, "type") <- switch(params$strip.position, left = , right = "rows", "cols")
462+
463+
labeller <- match.fun(params$labeller)
464+
list(facets = data_frame0(!!!labeller(labels)))
460465
}
461466
)
462467

man/get_strip_labels.Rd

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

man/render_strips.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-facet-strips.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,21 @@ test_that("strip clipping can be set from the theme", {
209209
expect_equal(strip$x$top[[1]]$layout$clip, "off")
210210
})
211211

212+
test_that("strip labels can be accessed", {
213+
214+
expect_null(get_strip_labels(ggplot()))
215+
216+
expect_equal(
217+
get_strip_labels(ggplot() + facet_wrap(vars("X", "Y"))),
218+
list(facets = data_frame0(`"X"` = "X", `"Y"` = "Y"))
219+
)
220+
221+
expect_equal(
222+
get_strip_labels(ggplot() + facet_grid(vars("X"), vars("Y"))),
223+
list(
224+
cols = data_frame0(`"Y"` = "Y"),
225+
rows = data_frame0(`"X"` = "X")
226+
)
227+
)
228+
})
229+

0 commit comments

Comments
 (0)