Skip to content

Commit 995b40c

Browse files
authored
Move coord clipping responsibility from facet to coord (#5953)
* move panel assembly to coord * move panel clipping responsibility from facets to coords * coord_radial uses clipping path * only apply clipping mask when possibly supported * add news bullet * turn on strip clipping by default * remove superfluous `clip` argument * add another bullet * reminder for the future
1 parent 2071c97 commit 995b40c

12 files changed

+111
-88
lines changed

NEWS.md

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

3+
* `coord_radial(clip = "on")` clips to the panel area when the graphics device
4+
supports clipping paths (@teunbrand, #5952).
5+
* (internal) Panel clipping responsibility moved from Facet class to Coord
6+
class through new `Coord$draw_panel()` method.
7+
* `theme(strip.clip)` now defaults to `"on"` and is independent of Coord
8+
clipping (@teunbrand, 5952).
9+
* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand).
310
* Axis labels are now justified across facet panels (@teunbrand, #5820)
411
* Fixed bug in `stat_function()` so x-axis title now produced automatically
512
when no data added. (@phispu, #5647).

R/coord-.R

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,20 @@ Coord <- ggproto("Coord",
208208
# used as a fudge for CoordFlip and CoordPolar
209209
modify_scales = function(scales_x, scales_y) {
210210
invisible()
211+
},
212+
213+
draw_panel = function(self, panel, params, theme) {
214+
fg <- self$render_fg(params, theme)
215+
bg <- self$render_bg(params, theme)
216+
if (isTRUE(theme$panel.ontop)) {
217+
panel <- list2(!!!panel, bg, fg)
218+
} else {
219+
panel <- list2(bg, !!!panel, fg)
220+
}
221+
gTree(
222+
children = inject(gList(!!!panel)),
223+
vp = viewport(clip = self$clip)
224+
)
211225
}
212226
)
213227

R/coord-radial.R

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,27 @@ CoordRadial <- ggproto("CoordRadial", Coord,
409409
)
410410
},
411411

412+
413+
draw_panel = function(self, panel, params, theme) {
414+
clip_support <- check_device("clippingPaths", "test", maybe = TRUE)
415+
if (self$clip == "on" && !isFALSE(clip_support)) {
416+
clip_path <- data_frame0(
417+
x = c(Inf, Inf, -Inf, -Inf),
418+
y = c(Inf, -Inf, -Inf, Inf)
419+
)
420+
clip_path <- coord_munch(self, clip_path, params, is_closed = TRUE)
421+
clip_path <- polygonGrob(clip_path$x, clip_path$y)
422+
# Note that clipping path is applied to panel without coord
423+
# foreground/background (added in parent method).
424+
# These may contain decorations that needn't be clipped
425+
panel <- list(gTree(
426+
children = inject(gList(!!!panel)),
427+
vp = viewport(clip = clip_path)
428+
))
429+
}
430+
ggproto_parent(Coord, self)$draw_panel(panel, params, theme)
431+
},
432+
412433
labels = function(self, labels, panel_params) {
413434
# `Layout$resolve_label()` doesn't know to look for theta/r/r.sec guides,
414435
# so we'll handle title propagation here.

R/facet-.R

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ Facet <- ggproto("Facet", NULL,
153153

154154
table <- self$init_gtable(
155155
panels, layout, theme, ranges, params,
156-
aspect_ratio = aspect_ratio %||% coord$aspect(ranges[[1]]),
157-
clip = coord$clip
156+
aspect_ratio = aspect_ratio %||% coord$aspect(ranges[[1]])
158157
)
159158

160159
table <- self$attach_axes(table, layout, ranges, coord, theme, params)
@@ -198,7 +197,7 @@ Facet <- ggproto("Facet", NULL,
198197
data
199198
},
200199
init_gtable = function(panels, layout, theme, ranges, params,
201-
aspect_ratio = NULL, clip = "on") {
200+
aspect_ratio = NULL) {
202201

203202
# Initialise matrix of panels
204203
dim <- c(max(layout$ROW), max(layout$COL))
@@ -228,7 +227,7 @@ Facet <- ggproto("Facet", NULL,
228227
"layout", table,
229228
widths = widths, heights = heights,
230229
respect = !is.null(aspect_ratio),
231-
clip = clip, z = matrix(1, dim[1], dim[2])
230+
clip = "off", z = matrix(1, dim[1], dim[2])
232231
)
233232

234233
# Set panel names

R/facet-grid-.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,13 +404,13 @@ FacetGrid <- ggproto("FacetGrid", Facet,
404404
space <- if (!inside_x & table_has_grob(table, "axis-b")) padding
405405
table <- seam_table(
406406
table, strips$x$bottom, side = "bottom", name = "strip-b",
407-
shift = shift_x, z = 2, clip = "on", spacing = space
407+
shift = shift_x, z = 2, clip = "off", spacing = space
408408
)
409409
} else {
410410
space <- if (!inside_x & table_has_grob(table, "axis-t")) padding
411411
table <- seam_table(
412412
table, strips$x$top, side = "top", name = "strip-t",
413-
shift = shift_x, z = 2, clip = "on", spacing = space
413+
shift = shift_x, z = 2, clip = "off", spacing = space
414414
)
415415
}
416416

@@ -422,13 +422,13 @@ FacetGrid <- ggproto("FacetGrid", Facet,
422422
space <- if (!inside_y & table_has_grob(table, "axis-l")) padding
423423
table <- seam_table(
424424
table, strips$y$left, side = "left", name = "strip-l",
425-
shift = shift_y, z = 2, clip = "on", spacing = space
425+
shift = shift_y, z = 2, clip = "off", spacing = space
426426
)
427427
} else {
428428
space <- if (!inside_y & table_has_grob(table, "axis-r")) padding
429429
table <- seam_table(
430430
table, strips$y$right, side = "right", name = "strip-r",
431-
shift = shift_y, z = 2, clip = "on", spacing = space
431+
shift = shift_y, z = 2, clip = "off", spacing = space
432432
)
433433
}
434434
table

R/facet-null.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ FacetNull <- ggproto("FacetNull", Facet,
6363
grob_widths <- unit.c(grobWidth(axis_v$left), unit(1, "null"), grobWidth(axis_v$right))
6464
grob_heights <- unit.c(grobHeight(axis_h$top), unit(abs(aspect_ratio), "null"), grobHeight(axis_h$bottom))
6565
grob_names <- c("spacer", "axis-l", "spacer", "axis-t", "panel", "axis-b", "spacer", "axis-r", "spacer")
66-
grob_clip <- c("off", "off", "off", "off", coord$clip, "off", "off", "off", "off")
6766

6867
layout <- gtable_matrix("layout", all,
6968
widths = grob_widths, heights = grob_heights,
70-
respect = respect, clip = grob_clip,
69+
respect = respect, clip = "off",
7170
z = z_matrix
7271
)
7372
layout$layout$name <- grob_names

R/facet-wrap.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ FacetWrap <- ggproto("FacetWrap", Facet,
405405
shift <- if (inside) shift[1] else shift[2]
406406
size <- unit(size, "cm")
407407

408-
table <- weave(table, mat, shift, size, name = prefix, z = 2, clip = "on")
408+
table <- weave(table, mat, shift, size, name = prefix, z = 2, clip = "off")
409409

410410
if (!inside) {
411411
axes <- grepl(paste0("axis-", pos), table$layout$name)

R/layout.R

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,8 @@ Layout <- ggproto("Layout", NULL,
8080
panels <- lapply(seq_along(panels[[1]]), function(i) {
8181
panel <- lapply(panels, `[[`, i)
8282
panel <- c(facet_bg[i], panel, facet_fg[i])
83-
84-
coord_fg <- self$coord$render_fg(self$panel_params[[i]], theme)
85-
coord_bg <- self$coord$render_bg(self$panel_params[[i]], theme)
86-
if (isTRUE(theme$panel.ontop)) {
87-
panel <- c(panel, list(coord_bg), list(coord_fg))
88-
} else {
89-
panel <- c(list(coord_bg), panel, list(coord_fg))
90-
}
91-
92-
ggname(
93-
paste("panel", i, sep = "-"),
94-
gTree(children = inject(gList(!!!panel)))
95-
)
83+
panel <- self$coord$draw_panel(panel, self$panel_params[[i]], theme)
84+
ggname(paste("panel", i, sep = "-"), panel)
9685
})
9786
plot_table <- self$facet$draw_panels(
9887
panels,

R/theme-defaults.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ theme_grey <- function(base_size = 11, base_family = "",
212212
panel.ontop = FALSE,
213213

214214
strip.background = element_rect(fill = "grey85", colour = NA),
215-
strip.clip = "inherit",
215+
strip.clip = "on",
216216
strip.text = element_text(
217217
colour = "grey10",
218218
size = rel(0.8),
@@ -511,7 +511,7 @@ theme_void <- function(base_size = 11, base_family = "",
511511
legend.box.margin = rel(0),
512512
legend.box.spacing = unit(0.2, "cm"),
513513
legend.ticks.length = rel(0.2),
514-
strip.clip = "inherit",
514+
strip.clip = "on",
515515
strip.text = element_text(size = rel(0.8)),
516516
strip.switch.pad.grid = rel(0.5),
517517
strip.switch.pad.wrap = rel(0.5),
@@ -643,7 +643,7 @@ theme_test <- function(base_size = 11, base_family = "",
643643
panel.ontop = FALSE,
644644

645645
strip.background = element_rect(fill = "grey85", colour = "grey20"),
646-
strip.clip = "inherit",
646+
strip.clip = "on",
647647
strip.text = element_text(
648648
colour = "grey10",
649649
size = rel(0.8),

tests/testthat/_snaps/facet-/facet-wrap-with-omitted-inner-axis-labels.svg

Lines changed: 52 additions & 25 deletions
Loading

tests/testthat/_snaps/facet-layout/axes-are-positioned-correctly-in-non-table-layout.svg

Lines changed: 0 additions & 36 deletions
Loading

tests/testthat/test-coord-polar.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ test_that("bounding box calculations are sensible", {
158158

159159
# Visual tests ------------------------------------------------------------
160160

161+
#TODO: Once {vdiffr} supports non-rectangular clipping paths, we should add a
162+
# test for `coord_radial(clip = "on")`'s ability to clip to the sector
163+
161164
test_that("polar coordinates draw correctly", {
162165
theme <- theme_test() +
163166
theme(

0 commit comments

Comments
 (0)