Skip to content

Commit c95e061

Browse files
authored
Reduce panel parameter setup in facetted plots (#5431)
* coords append information to layout * compute panel params/guides once per scale combination * Facets render axes once per x/y combination * anonymous function to `MoreArgs` * Sprinkle some comments * Add news bullet * add test * format bullet
1 parent af8e236 commit c95e061

File tree

5 files changed

+52
-9
lines changed

5 files changed

+52
-9
lines changed

NEWS.md

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

3-
* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand).
3+
* (internal) The plot's layout now has a coord parameter that is used to
4+
prevent setting up identical panel parameters (#5427)
5+
* (internal) rearranged the code of `Facet$draw_panels()` method (@teunbrand).
46
* `geom_rug()` prints a warning when `na.rm = FALSE`, as per documentation (@pn317, #5905)
57
* `position_dodge(preserve = "single")` now handles multi-row geoms better,
68
such as `geom_violin()` (@teunbrand based on @clauswilke's work, #2801).

R/coord-.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ Coord <- ggproto("Coord",
196196
},
197197

198198
setup_layout = function(layout, params) {
199+
# We're appending a COORD variable to the layout that determines the
200+
# uniqueness of panel parameters. The layout uses this to prevent redundant
201+
# setups of these parameters.
202+
scales <- layout[c("SCALE_X", "SCALE_Y")]
203+
layout$COORD <- vec_match(scales, unique0(scales))
199204
layout
200205
},
201206

R/coord-flip.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ CoordFlip <- ggproto("CoordFlip", CoordCartesian,
9999
},
100100

101101
setup_layout = function(layout, params) {
102+
layout <- Coord$setup_layout(layout, params)
102103
# Switch the scales
103104
layout[c("SCALE_X", "SCALE_Y")] <- layout[c("SCALE_Y", "SCALE_X")]
104105
layout

R/layout.R

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,20 +212,32 @@ Layout <- ggproto("Layout", NULL,
212212
# scales is not elegant, but it is pragmatic
213213
self$coord$modify_scales(self$panel_scales_x, self$panel_scales_y)
214214

215-
scales_x <- self$panel_scales_x[self$layout$SCALE_X]
216-
scales_y <- self$panel_scales_y[self$layout$SCALE_Y]
215+
# We only need to setup panel params once for unique combinations of x/y
216+
# scales. These will be repeated for duplicated combinations.
217+
index <- vec_unique_loc(self$layout$COORD)
218+
order <- vec_match(self$layout$COORD, self$layout$COORD[index])
217219

218-
setup_panel_params <- function(scale_x, scale_y) {
219-
self$coord$setup_panel_params(scale_x, scale_y, params = self$coord_params)
220-
}
221-
self$panel_params <- Map(setup_panel_params, scales_x, scales_y)
220+
scales_x <- self$panel_scales_x[self$layout$SCALE_X[index]]
221+
scales_y <- self$panel_scales_y[self$layout$SCALE_Y[index]]
222+
223+
self$panel_params <- Map(
224+
self$coord$setup_panel_params,
225+
scales_x, scales_y,
226+
MoreArgs = list(params = self$coord_params)
227+
)[order] # `[order]` does the repeating
222228

223229
invisible()
224230
},
225231

226232
setup_panel_guides = function(self, guides, layers) {
233+
234+
# Like in `setup_panel_params`, we only need to setup guides for unique
235+
# combinations of x/y scales.
236+
index <- vec_unique_loc(self$layout$COORD)
237+
order <- vec_match(self$layout$COORD, self$layout$COORD[index])
238+
227239
self$panel_params <- lapply(
228-
self$panel_params,
240+
self$panel_params[index],
229241
self$coord$setup_panel_guides,
230242
guides,
231243
self$coord_params
@@ -236,7 +248,7 @@ Layout <- ggproto("Layout", NULL,
236248
self$coord$train_panel_guides,
237249
layers,
238250
self$coord_params
239-
)
251+
)[order]
240252

241253
invisible()
242254
},

tests/testthat/test-coord-.R

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,26 @@ test_that("check coord limits errors only on bad inputs", {
5353
# Should raise error if vector of wrong length is passed
5454
expect_error(check_coord_limits(1:3))
5555
})
56+
57+
test_that("coords append a column to the layout correctly", {
58+
layout <- data_frame0(SCALE_X = c(1, 1, 1), SCALE_Y = c(1, 1, 1))
59+
test <- Coord$setup_layout(layout)
60+
expect_equal(test$COORD, c(1, 1, 1))
61+
62+
layout <- data_frame0(SCALE_X = c(1, 1, 1), SCALE_Y = c(1, 2, 2))
63+
test <- Coord$setup_layout(layout)
64+
expect_equal(test$COORD, c(1, 2, 2))
65+
66+
layout <- data_frame0(SCALE_X = c(1, 2, 3), SCALE_Y = c(1, 1, 1))
67+
test <- Coord$setup_layout(layout)
68+
expect_equal(test$COORD, c(1, 2, 3))
69+
70+
layout <- data_frame0(SCALE_X = c(1, 2, 3), SCALE_Y = c(1, 2, 3))
71+
test <- Coord$setup_layout(layout)
72+
expect_equal(test$COORD, c(1, 2, 3))
73+
74+
layout <- data_frame0(SCALE_X = c(1, 1, 1), SCALE_Y = c(1, 2, 1))
75+
test <- Coord$setup_layout(layout)
76+
expect_equal(test$COORD, c(1, 2, 1))
77+
})
78+

0 commit comments

Comments
 (0)