Skip to content

Commit 0eadf1b

Browse files
clauswilkehadley
authored andcommitted
Make clipping configurable. Closes #2536 (#2539)
* Make clipping configurable. Closes #2536 * panel clip settings should not be applied to facet strips. * reference user name and github issue * Move news statement to the correct news file. NEWS is not in use anymore, NEWS.md is current. * Add visual tests for clipping * update documentation for clipping option * Simplify visual tests to just two, fix documentation bug * rebase and fix visual tests
1 parent b81156a commit 0eadf1b

23 files changed

+226
-26
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ up correct aspect ratio, and draws a graticule.
318318

319319
### Other
320320

321+
* Clipping to the plot panel is now configurable, through a `clip` argument
322+
to coordinate systems, e.g. `coord_cartesian(clip = "off")`. (@clauswilke, #2536)
323+
321324
* `fortify()` gains a method for tbls (@karawoo, #2218)
322325

323326
* `ggplot` gains a method for `grouped_df`s that adds a `.group` variable,

R/coord-.r

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Coord <- ggproto("Coord",
3535
# Is this the default coordinate system?
3636
default = FALSE,
3737

38+
# should drawing be clipped to the extent of the plot panel?
39+
# "on" = yes, "off" = no
40+
clip = "on",
41+
3842
aspect = function(ranges) NULL,
3943

4044
labels = function(panel_params) panel_params,

R/coord-cartesian-.r

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
#' the limits to ensure that data and axes don't overlap. If `FALSE`,
1111
#' limits are taken exactly from the data or `xlim`/`ylim`.
1212
#' @param default Is this the default coordinate system? If `FALSE`
13+
#' @param clip Should drawing be clipped to the extent of the plot panel? A
14+
#' setting of `"on"` (the default) means yes, and a setting of `"off"`
15+
#' means no. In most cases, the default of `"on"` should not be changed,
16+
#' as setting `clip = "off"` can cause unexpected results. It allows
17+
#' drawing of data points anywhere on the plot, including in the plot margins. If
18+
#' limits are set via `xlim` and `ylim` and some data points fall outside those
19+
#' limits, then those data points may show up in places such as the axes, the
20+
#' legend, the plot title, or the plot margins.
1321
#' @export
1422
#' @examples
1523
#' # There are two ways of zooming the plot display: with scales or
@@ -49,11 +57,12 @@
4957
#' # displayed bigger
5058
#' d + coord_cartesian(xlim = c(0, 1))
5159
coord_cartesian <- function(xlim = NULL, ylim = NULL, expand = TRUE,
52-
default = FALSE) {
60+
default = FALSE, clip = "on") {
5361
ggproto(NULL, CoordCartesian,
5462
limits = list(x = xlim, y = ylim),
5563
expand = expand,
56-
default = default
64+
default = default,
65+
clip = clip
5766
)
5867
}
5968

R/coord-fixed.r

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
#' p + coord_fixed(xlim = c(15, 30))
2323
#'
2424
#' # Resize the plot to see that the specified aspect ratio is maintained
25-
coord_fixed <- function(ratio = 1, xlim = NULL, ylim = NULL, expand = TRUE) {
25+
coord_fixed <- function(ratio = 1, xlim = NULL, ylim = NULL, expand = TRUE, clip = "on") {
2626
ggproto(NULL, CoordFixed,
2727
limits = list(x = xlim, y = ylim),
2828
ratio = ratio,
29-
expand = expand
29+
expand = expand,
30+
clip = clip
3031
)
3132
}
3233

R/coord-flip.r

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@
2525
#' ggplot(df, aes(x, y)) +
2626
#' geom_area()
2727
#' last_plot() + coord_flip()
28-
coord_flip <- function(xlim = NULL, ylim = NULL, expand = TRUE) {
28+
coord_flip <- function(xlim = NULL, ylim = NULL, expand = TRUE, clip = "on") {
2929
ggproto(NULL, CoordFlip,
3030
limits = list(x = xlim, y = ylim),
31-
expand = expand
31+
expand = expand,
32+
clip = clip
3233
)
3334
}
3435

R/coord-map.r

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#' [mapproj::mapproject()] for more information.
3131
#' @param xlim,ylim Manually specific x/y limits (in degrees of
3232
#' longitude/latitude)
33+
#' @param clip Should drawing be clipped to the extent of the plot panel? A
34+
#' setting of `"on"` (the default) means yes, and a setting of `"off"`
35+
#' means no. For details, please see [`coord_cartesian()`].
3336
#' @export
3437
#' @examples
3538
#' if (require("maps")) {
@@ -85,7 +88,7 @@
8588
#' # Centered on New York (currently has issues with closing polygons)
8689
#' worldmap + coord_map("ortho", orientation = c(41, -74, 0))
8790
#' }
88-
coord_map <- function(projection="mercator", ..., parameters = NULL, orientation = NULL, xlim = NULL, ylim = NULL) {
91+
coord_map <- function(projection="mercator", ..., parameters = NULL, orientation = NULL, xlim = NULL, ylim = NULL, clip = "on") {
8992
if (is.null(parameters)) {
9093
params <- list(...)
9194
} else {
@@ -96,7 +99,8 @@ coord_map <- function(projection="mercator", ..., parameters = NULL, orientation
9699
projection = projection,
97100
orientation = orientation,
98101
limits = list(x = xlim, y = ylim),
99-
params = params
102+
params = params,
103+
clip = clip
100104
)
101105
}
102106

R/coord-polar.r

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#' @param theta variable to map angle to (`x` or `y`)
77
#' @param start offset of starting point from 12 o'clock in radians
88
#' @param direction 1, clockwise; -1, anticlockwise
9+
#' @param clip Should drawing be clipped to the extent of the plot panel? A
10+
#' setting of `"on"` (the default) means yes, and a setting of `"off"`
11+
#' means no. For details, please see [`coord_cartesian()`].
912
#' @export
1013
#' @examples
1114
#' # NOTE: Use these plots with caution - polar coordinates has
@@ -54,15 +57,16 @@
5457
#' doh + geom_bar(width = 0.9, position = "fill") + coord_polar(theta = "y")
5558
#' }
5659
#' }
57-
coord_polar <- function(theta = "x", start = 0, direction = 1) {
60+
coord_polar <- function(theta = "x", start = 0, direction = 1, clip = "on") {
5861
theta <- match.arg(theta, c("x", "y"))
5962
r <- if (theta == "x") "y" else "x"
6063

6164
ggproto(NULL, CoordPolar,
6265
theta = theta,
6366
r = r,
6467
start = start,
65-
direction = sign(direction)
68+
direction = sign(direction),
69+
clip = clip
6670
)
6771
}
6872

R/coord-quickmap.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#' @inheritParams coord_cartesian
22
#' @export
33
#' @rdname coord_map
4-
coord_quickmap <- function(xlim = NULL, ylim = NULL, expand = TRUE) {
4+
coord_quickmap <- function(xlim = NULL, ylim = NULL, expand = TRUE, clip = "on") {
55
ggproto(NULL, CoordQuickmap,
66
limits = list(x = xlim, y = ylim),
7-
expand = expand
7+
expand = expand,
8+
clip = clip
89
)
910
}
1011

R/coord-transform.r

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#' @param xtrans,ytrans Deprecated; use `x` and `y` instead.
1313
#' @param limx,limy limits for x and y axes. (Named so for backward
1414
#' compatibility)
15+
#' @param clip Should drawing be clipped to the extent of the plot panel? A
16+
#' setting of `"on"` (the default) means yes, and a setting of `"off"`
17+
#' means no. For details, please see [`coord_cartesian()`].
1518
#' @export
1619
#' @examples
1720
#' \donttest{
@@ -75,7 +78,7 @@
7578
#' plot + coord_trans(x = "log10")
7679
#' plot + coord_trans(x = "sqrt")
7780
#' }
78-
coord_trans <- function(x = "identity", y = "identity", limx = NULL, limy = NULL,
81+
coord_trans <- function(x = "identity", y = "identity", limx = NULL, limy = NULL, clip = "on",
7982
xtrans, ytrans)
8083
{
8184
if (!missing(xtrans)) {
@@ -99,7 +102,8 @@ coord_trans <- function(x = "identity", y = "identity", limx = NULL, limy = NULL
99102

100103
ggproto(NULL, CoordTrans,
101104
trans = list(x = x, y = y),
102-
limits = list(x = limx, y = limy)
105+
limits = list(x = limx, y = limy),
106+
clip = clip
103107
)
104108
}
105109

R/facet-grid-.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ FacetGrid <- ggproto("FacetGrid", Facet,
374374
}
375375

376376
panel_table <- gtable_matrix("layout", panel_table,
377-
panel_widths, panel_heights, respect = respect, clip = "on", z = matrix(1, ncol = ncol, nrow = nrow))
377+
panel_widths, panel_heights, respect = respect, clip = coord$clip, z = matrix(1, ncol = ncol, nrow = nrow))
378378
panel_table$layout$name <- paste0('panel-', rep(seq_len(ncol), nrow), '-', rep(seq_len(nrow), each = ncol))
379379

380380
panel_table <- gtable_add_col_space(panel_table,

R/facet-null.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ 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(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", "on", "off", "off", "off", "off")
66+
grob_clip <- c("off", "off", "off", "off", coord$clip, "off", "off", "off", "off")
6767

6868
layout <- gtable_matrix("layout", all,
6969
widths = grob_widths, heights = grob_heights,

R/facet-wrap.r

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ FacetWrap <- ggproto("FacetWrap", Facet,
259259
empties <- apply(panel_table, c(1,2), function(x) is.zero(x[[1]]))
260260
panel_table <- gtable_matrix("layout", panel_table,
261261
widths = unit(rep(1, ncol), "null"),
262-
heights = unit(rep(aspect_ratio, nrow), "null"), respect = respect, clip = "on", z = matrix(1, ncol = ncol, nrow = nrow))
262+
heights = unit(rep(aspect_ratio, nrow), "null"), respect = respect, clip = coord$clip, z = matrix(1, ncol = ncol, nrow = nrow))
263263
panel_table$layout$name <- paste0('panel-', rep(seq_len(ncol), nrow), '-', rep(seq_len(nrow), each = ncol))
264264

265265
panel_table <- gtable_add_col_space(panel_table,
@@ -332,7 +332,7 @@ FacetWrap <- ggproto("FacetWrap", Facet,
332332
strip_pad <- axis_height_bottom
333333
}
334334
strip_height <- unit(apply(strip_mat, 1, max_height), "cm")
335-
panel_table <- weave_tables_row(panel_table, strip_mat, placement, strip_height, strip_name, 2, "on")
335+
panel_table <- weave_tables_row(panel_table, strip_mat, placement, strip_height, strip_name, 2, coord$clip)
336336
if (!inside) {
337337
strip_pad[unclass(strip_pad) != 0] <- strip_padding
338338
panel_table <- weave_tables_row(panel_table, row_shift = placement, row_height = strip_pad)
@@ -348,7 +348,7 @@ FacetWrap <- ggproto("FacetWrap", Facet,
348348
}
349349
strip_pad[unclass(strip_pad) != 0] <- strip_padding
350350
strip_width <- unit(apply(strip_mat, 2, max_width), "cm")
351-
panel_table <- weave_tables_col(panel_table, strip_mat, placement, strip_width, strip_name, 2, "on")
351+
panel_table <- weave_tables_col(panel_table, strip_mat, placement, strip_width, strip_name, 2, coord$clip)
352352
if (!inside) {
353353
strip_pad[unclass(strip_pad) != 0] <- strip_padding
354354
panel_table <- weave_tables_col(panel_table, col_shift = placement, col_width = strip_pad)

man/coord_cartesian.Rd

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

man/coord_fixed.Rd

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

man/coord_flip.Rd

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

man/coord_map.Rd

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

man/coord_polar.Rd

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

man/coord_trans.Rd

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

0 commit comments

Comments
 (0)