Skip to content

Commit 6704ea1

Browse files
authored
Consistent use of lineend and linejoin in geoms and keys (#4664)
1 parent aaaec2f commit 6704ea1

File tree

95 files changed

+1929
-1866
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1929
-1866
lines changed

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* All geoms now have consistent exposure of linejoin and lineend parameters, and
4+
the guide keys will now respect these settings (@thomasp85, #4653)
5+
36
* `geom_sf()` now respects `arrow` parameter for lines (@jakeruss, #4659)
47

58
* Updated documentation for `print.ggplot` to reflect that it returns

R/geom-abline.r

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ geom_abline <- function(mapping = NULL, data = NULL,
124124
#' @usage NULL
125125
#' @export
126126
GeomAbline <- ggproto("GeomAbline", Geom,
127-
draw_panel = function(data, panel_params, coord) {
127+
draw_panel = function(data, panel_params, coord, lineend = "butt") {
128128
ranges <- coord$backtransform_range(panel_params)
129129

130130
if (coord$clip == "on" && coord$is_linear()) {
@@ -138,7 +138,7 @@ GeomAbline <- ggproto("GeomAbline", Geom,
138138
data$y <- ranges$x[1] * data$slope + data$intercept
139139
data$yend <- ranges$x[2] * data$slope + data$intercept
140140

141-
GeomSegment$draw_panel(unique(data), panel_params, coord)
141+
GeomSegment$draw_panel(unique(data), panel_params, coord, lineend = lineend)
142142
},
143143

144144
default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA),

R/geom-bar.r

+9-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,15 @@ GeomBar <- ggproto("GeomBar", GeomRect,
137137
flip_data(data, params$flipped_aes)
138138
},
139139

140-
draw_panel = function(self, data, panel_params, coord, width = NULL, flipped_aes = FALSE) {
140+
draw_panel = function(self, data, panel_params, coord, lineend = "butt",
141+
linejoin = "mitre", width = NULL, flipped_aes = FALSE) {
141142
# Hack to ensure that width is detected as a parameter
142-
ggproto_parent(GeomRect, self)$draw_panel(data, panel_params, coord)
143+
ggproto_parent(GeomRect, self)$draw_panel(
144+
data,
145+
panel_params,
146+
coord,
147+
lineend = lineend,
148+
linejoin = linejoin
149+
)
143150
}
144151
)

R/geom-boxplot.r

+15-7
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,12 @@ GeomBoxplot <- ggproto("GeomBoxplot", Geom,
205205
flip_data(data, params$flipped_aes)
206206
},
207207

208-
draw_group = function(data, panel_params, coord, fatten = 2,
209-
outlier.colour = NULL, outlier.fill = NULL,
210-
outlier.shape = 19,
208+
draw_group = function(data, panel_params, coord, lineend = "butt",
209+
linejoin = "mitre", fatten = 2, outlier.colour = NULL,
210+
outlier.fill = NULL, outlier.shape = 19,
211211
outlier.size = 1.5, outlier.stroke = 0.5,
212-
outlier.alpha = NULL,
213-
notch = FALSE, notchwidth = 0.5, varwidth = FALSE, flipped_aes = FALSE) {
212+
outlier.alpha = NULL, notch = FALSE, notchwidth = 0.5,
213+
varwidth = FALSE, flipped_aes = FALSE) {
214214
data <- flip_data(data, flipped_aes)
215215
# this may occur when using geom_boxplot(stat = "identity")
216216
if (nrow(data) != 1) {
@@ -274,8 +274,16 @@ GeomBoxplot <- ggproto("GeomBoxplot", Geom,
274274

275275
ggname("geom_boxplot", grobTree(
276276
outliers_grob,
277-
GeomSegment$draw_panel(whiskers, panel_params, coord),
278-
GeomCrossbar$draw_panel(box, fatten = fatten, panel_params, coord, flipped_aes = flipped_aes)
277+
GeomSegment$draw_panel(whiskers, panel_params, coord, lineend = lineend),
278+
GeomCrossbar$draw_panel(
279+
box,
280+
fatten = fatten,
281+
panel_params,
282+
coord,
283+
lineend = lineend,
284+
linejoin = linejoin,
285+
flipped_aes = flipped_aes
286+
)
279287
))
280288
},
281289

R/geom-col.r

+9-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,15 @@ GeomCol <- ggproto("GeomCol", GeomRect,
5656
flip_data(data, params$flipped_aes)
5757
},
5858

59-
draw_panel = function(self, data, panel_params, coord, width = NULL, flipped_aes = FALSE) {
59+
draw_panel = function(self, data, panel_params, coord, lineend = "butt",
60+
linejoin = "mitre", width = NULL, flipped_aes = FALSE) {
6061
# Hack to ensure that width is detected as a parameter
61-
ggproto_parent(GeomRect, self)$draw_panel(data, panel_params, coord)
62+
ggproto_parent(GeomRect, self)$draw_panel(
63+
data,
64+
panel_params,
65+
coord,
66+
lineend = lineend,
67+
linejoin = linejoin
68+
)
6269
}
6370
)

R/geom-crossbar.r

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ GeomCrossbar <- ggproto("GeomCrossbar", Geom,
4747

4848
draw_key = draw_key_crossbar,
4949

50-
draw_panel = function(data, panel_params, coord, fatten = 2.5, width = NULL, flipped_aes = FALSE) {
50+
draw_panel = function(data, panel_params, coord, lineend = "butt",
51+
linejoin = "mitre", fatten = 2.5, width = NULL,
52+
flipped_aes = FALSE) {
5153
data <- flip_data(data, flipped_aes)
5254

5355
middle <- transform(data, x = xmin, xend = xmax, yend = y, size = size * fatten, alpha = NA)
@@ -99,8 +101,8 @@ GeomCrossbar <- ggproto("GeomCrossbar", Geom,
99101
middle <- flip_data(middle, flipped_aes)
100102

101103
ggname("geom_crossbar", gTree(children = gList(
102-
GeomPolygon$draw_panel(box, panel_params, coord),
103-
GeomSegment$draw_panel(middle, panel_params, coord)
104+
GeomPolygon$draw_panel(box, panel_params, coord, lineend = lineend, linejoin = linejoin),
105+
GeomSegment$draw_panel(middle, panel_params, coord, lineend = lineend, linejoin = linejoin)
104106
)))
105107
}
106108
)

R/geom-dotplot.r

+3-2
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ GeomDotplot <- ggproto("GeomDotplot", Geom,
264264
},
265265

266266

267-
draw_group = function(data, panel_params, coord, na.rm = FALSE,
267+
draw_group = function(data, panel_params, coord, lineend = "butt", na.rm = FALSE,
268268
binaxis = "x", stackdir = "up", stackratio = 1,
269269
dotsize = 1, stackgroups = FALSE) {
270270
if (!coord$is_linear()) {
@@ -292,7 +292,8 @@ GeomDotplot <- ggproto("GeomDotplot", Geom,
292292
default.units = "npc",
293293
gp = gpar(col = alpha(tdata$colour, tdata$alpha),
294294
fill = alpha(tdata$fill, tdata$alpha),
295-
lwd = tdata$stroke, lty = tdata$linetype))
295+
lwd = tdata$stroke, lty = tdata$linetype,
296+
lineend = lineend))
296297
)
297298
},
298299

R/geom-errorbar.r

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ GeomErrorbar <- ggproto("GeomErrorbar", Geom,
5252
flip_data(data, params$flipped_aes)
5353
},
5454

55-
draw_panel = function(data, panel_params, coord, width = NULL, flipped_aes = FALSE) {
55+
draw_panel = function(data, panel_params, coord, lineend = "butt", width = NULL, flipped_aes = FALSE) {
5656
data <- flip_data(data, flipped_aes)
5757
x <- as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x, NA, data$xmin, data$xmax))
5858
y <- as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$ymin, NA, data$ymin, data$ymin))
@@ -67,6 +67,6 @@ GeomErrorbar <- ggproto("GeomErrorbar", Geom,
6767
row.names = 1:(nrow(data) * 8)
6868
))
6969
data <- flip_data(data, flipped_aes)
70-
GeomPath$draw_panel(data, panel_params, coord)
70+
GeomPath$draw_panel(data, panel_params, coord, lineend = lineend)
7171
}
7272
)

R/geom-errorbarh.r

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ GeomErrorbarh <- ggproto("GeomErrorbarh", Geom,
6767
)
6868
},
6969

70-
draw_panel = function(data, panel_params, coord, height = NULL) {
70+
draw_panel = function(data, panel_params, coord, height = NULL, lineend = "butt") {
7171
GeomPath$draw_panel(new_data_frame(list(
7272
x = as.vector(rbind(data$xmax, data$xmax, NA, data$xmax, data$xmin, NA, data$xmin, data$xmin)),
7373
y = as.vector(rbind(data$ymin, data$ymax, NA, data$y, data$y, NA, data$ymin, data$ymax)),
@@ -77,6 +77,6 @@ GeomErrorbarh <- ggproto("GeomErrorbarh", Geom,
7777
linetype = rep(data$linetype, each = 8),
7878
group = rep(1:(nrow(data)), each = 8),
7979
row.names = 1:(nrow(data) * 8)
80-
)), panel_params, coord)
80+
)), panel_params, coord, lineend = lineend)
8181
}
8282
)

R/geom-hex.r

+6-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ geom_hex <- function(mapping = NULL, data = NULL,
5454
#' @usage NULL
5555
#' @export
5656
GeomHex <- ggproto("GeomHex", Geom,
57-
draw_group = function(data, panel_params, coord) {
57+
draw_group = function(data, panel_params, coord, lineend = "butt",
58+
linejoin = "mitre", linemitre = 10) {
5859
if (!inherits(coord, "CoordCartesian")) {
5960
abort("geom_hex() only works with Cartesian coordinates")
6061
}
@@ -66,7 +67,10 @@ GeomHex <- ggproto("GeomHex", Geom,
6667
col = coords$colour,
6768
fill = alpha(coords$fill, coords$alpha),
6869
lwd = coords$size * .pt,
69-
lty = coords$linetype
70+
lty = coords$linetype,
71+
lineend = lineend,
72+
linejoin = linejoin,
73+
linemitre = linemitre
7074
)
7175
))
7276
},

R/geom-hline.r

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ geom_hline <- function(mapping = NULL, data = NULL,
4444
#' @usage NULL
4545
#' @export
4646
GeomHline <- ggproto("GeomHline", Geom,
47-
draw_panel = function(data, panel_params, coord) {
47+
draw_panel = function(data, panel_params, coord, lineend = "butt") {
4848
ranges <- coord$backtransform_range(panel_params)
4949

5050
data$x <- ranges$x[1]
5151
data$xend <- ranges$x[2]
5252
data$y <- data$yintercept
5353
data$yend <- data$yintercept
5454

55-
GeomSegment$draw_panel(unique(data), panel_params, coord)
55+
GeomSegment$draw_panel(unique(data), panel_params, coord, lineend = lineend)
5656
},
5757

5858
default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA),

R/geom-linerange.r

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ GeomLinerange <- ggproto("GeomLinerange", Geom,
113113
data
114114
},
115115

116-
draw_panel = function(data, panel_params, coord, flipped_aes = FALSE) {
116+
draw_panel = function(data, panel_params, coord, lineend = "butt", flipped_aes = FALSE) {
117117
data <- flip_data(data, flipped_aes)
118118
data <- transform(data, xend = x, y = ymin, yend = ymax)
119119
data <- flip_data(data, flipped_aes)
120-
ggname("geom_linerange", GeomSegment$draw_panel(data, panel_params, coord))
120+
ggname("geom_linerange", GeomSegment$draw_panel(data, panel_params, coord, lineend = lineend))
121121
}
122122
)

R/geom-map.r

+8-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ geom_map <- function(mapping = NULL, data = NULL,
105105
#' @usage NULL
106106
#' @export
107107
GeomMap <- ggproto("GeomMap", GeomPolygon,
108-
draw_panel = function(data, panel_params, coord, map) {
108+
draw_panel = function(data, panel_params, coord, lineend = "butt",
109+
linejoin = "round", linemitre = 10, map) {
109110
# Only use matching data and map ids
110111
common <- intersect(data$map_id, map$id)
111112
data <- data[data$map_id %in% common, , drop = FALSE]
@@ -123,8 +124,12 @@ GeomMap <- ggproto("GeomMap", GeomPolygon,
123124

124125
polygonGrob(coords$x, coords$y, default.units = "native", id = grob_id,
125126
gp = gpar(
126-
col = data$colour, fill = alpha(data$fill, data$alpha),
127-
lwd = data$size * .pt
127+
col = data$colour,
128+
fill = alpha(data$fill, data$alpha),
129+
lwd = data$size * .pt,
130+
lineend = lineend,
131+
linejoin = linejoin,
132+
linemitre = linemitre
128133
)
129134
)
130135
},

R/geom-pointrange.r

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ GeomPointrange <- ggproto("GeomPointrange", Geom,
4747
GeomLinerange$setup_data(data, params)
4848
},
4949

50-
draw_panel = function(data, panel_params, coord, fatten = 4, flipped_aes = FALSE) {
50+
draw_panel = function(data, panel_params, coord, lineend = "butt", fatten = 4, flipped_aes = FALSE) {
5151
if (is.null(data[[flipped_names(flipped_aes)$y]]))
52-
return(GeomLinerange$draw_panel(data, panel_params, coord, flipped_aes = flipped_aes))
52+
return(GeomLinerange$draw_panel(data, panel_params, coord, lineend = lineend, flipped_aes = flipped_aes))
5353

5454
ggname("geom_pointrange",
5555
gTree(children = gList(
56-
GeomLinerange$draw_panel(data, panel_params, coord, flipped_aes = flipped_aes),
56+
GeomLinerange$draw_panel(data, panel_params, coord, lineend = lineend, flipped_aes = flipped_aes),
5757
GeomPoint$draw_panel(transform(data, size = size * fatten), panel_params, coord)
5858
))
5959
)

R/geom-polygon.r

+10-3
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ geom_polygon <- function(mapping = NULL, data = NULL,
106106
#' @usage NULL
107107
#' @export
108108
GeomPolygon <- ggproto("GeomPolygon", Geom,
109-
draw_panel = function(data, panel_params, coord, rule = "evenodd") {
109+
draw_panel = function(data, panel_params, coord, rule = "evenodd", lineend = "butt",
110+
linejoin = "round", linemitre = 10) {
110111
n <- nrow(data)
111112
if (n == 1) return(zeroGrob())
112113

@@ -131,7 +132,10 @@ GeomPolygon <- ggproto("GeomPolygon", Geom,
131132
col = first_rows$colour,
132133
fill = alpha(first_rows$fill, first_rows$alpha),
133134
lwd = first_rows$size * .pt,
134-
lty = first_rows$linetype
135+
lty = first_rows$linetype,
136+
lineend = lineend,
137+
linejoin = linejoin,
138+
linemitre = linemitre
135139
)
136140
)
137141
)
@@ -159,7 +163,10 @@ GeomPolygon <- ggproto("GeomPolygon", Geom,
159163
col = first_rows$colour,
160164
fill = alpha(first_rows$fill, first_rows$alpha),
161165
lwd = first_rows$size * .pt,
162-
lty = first_rows$linetype
166+
lty = first_rows$linetype,
167+
lineend = lineend,
168+
linejoin = linejoin,
169+
linemitre = linemitre
163170
)
164171
)
165172
)

R/geom-rect.r

+3-5
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ GeomRect <- ggproto("GeomRect", Geom,
3333

3434
required_aes = c("xmin", "xmax", "ymin", "ymax"),
3535

36-
draw_panel = function(self, data, panel_params, coord, linejoin = "mitre") {
36+
draw_panel = function(self, data, panel_params, coord, lineend = "butt", linejoin = "mitre") {
3737
if (!coord$is_linear()) {
3838
aesthetics <- setdiff(
3939
names(data), c("x", "y", "xmin", "xmax", "ymin", "ymax")
@@ -43,7 +43,7 @@ GeomRect <- ggproto("GeomRect", Geom,
4343
poly <- rect_to_poly(row$xmin, row$xmax, row$ymin, row$ymax)
4444
aes <- new_data_frame(row[aesthetics])[rep(1,5), ]
4545

46-
GeomPolygon$draw_panel(cbind(poly, aes), panel_params, coord)
46+
GeomPolygon$draw_panel(cbind(poly, aes), panel_params, coord, lineend = lineend, linejoin = linejoin)
4747
})
4848

4949
ggname("bar", do.call("grobTree", polys))
@@ -61,9 +61,7 @@ GeomRect <- ggproto("GeomRect", Geom,
6161
lwd = coords$size * .pt,
6262
lty = coords$linetype,
6363
linejoin = linejoin,
64-
# `lineend` is a workaround for Windows and intentionally kept unexposed
65-
# as an argument. (c.f. https://github.com/tidyverse/ggplot2/issues/3037#issuecomment-457504667)
66-
lineend = if (identical(linejoin, "round")) "round" else "square"
64+
lineend = lineend
6765
)
6866
))
6967
}

R/geom-ribbon.r

+12-3
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ GeomRibbon <- ggproto("GeomRibbon", Geom,
104104
data
105105
},
106106

107-
draw_group = function(data, panel_params, coord, na.rm = FALSE, flipped_aes = FALSE, outline.type = "both") {
107+
draw_group = function(data, panel_params, coord, lineend = "butt",
108+
linejoin = "round", linemitre = 10, na.rm = FALSE,
109+
flipped_aes = FALSE, outline.type = "both") {
108110
data <- flip_data(data, flipped_aes)
109111
if (na.rm) data <- data[stats::complete.cases(data[c("x", "ymin", "ymax")]), ]
110112
data <- data[order(data$group), ]
@@ -158,7 +160,10 @@ GeomRibbon <- ggproto("GeomRibbon", Geom,
158160
fill = alpha(aes$fill, aes$alpha),
159161
col = if (is_full_outline) aes$colour else NA,
160162
lwd = if (is_full_outline) aes$size * .pt else 0,
161-
lty = if (is_full_outline) aes$linetype else 1
163+
lty = if (is_full_outline) aes$linetype else 1,
164+
lineend = lineend,
165+
linejoin = linejoin,
166+
linemitre = linemitre
162167
)
163168
)
164169

@@ -181,7 +186,11 @@ GeomRibbon <- ggproto("GeomRibbon", Geom,
181186
gp = gpar(
182187
col = aes$colour,
183188
lwd = aes$size * .pt,
184-
lty = aes$linetype)
189+
lty = aes$linetype,
190+
lineend = lineend,
191+
linejoin = linejoin,
192+
linemitre = linemitre
193+
)
185194
)
186195

187196
ggname("geom_ribbon", grobTree(g_poly, g_lines))

R/geom-rug.r

+8-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ geom_rug <- function(mapping = NULL, data = NULL,
8888
GeomRug <- ggproto("GeomRug", Geom,
8989
optional_aes = c("x", "y"),
9090

91-
draw_panel = function(data, panel_params, coord, sides = "bl", outside = FALSE, length = unit(0.03, "npc")) {
91+
draw_panel = function(data, panel_params, coord, lineend = "butt", sides = "bl",
92+
outside = FALSE, length = unit(0.03, "npc")) {
9293
if (!inherits(length, "unit")) {
9394
abort("'length' must be a 'unit' object.")
9495
}
@@ -108,7 +109,12 @@ GeomRug <- ggproto("GeomRug", Geom,
108109
list(min = -1 * length, max = unit(1, "npc") + length)
109110
}
110111

111-
gp <- gpar(col = alpha(data$colour, data$alpha), lty = data$linetype, lwd = data$size * .pt)
112+
gp <- gpar(
113+
col = alpha(data$colour, data$alpha),
114+
lty = data$linetype,
115+
lwd = data$size * .pt,
116+
lineend = lineend
117+
)
112118
if (!is.null(data$x)) {
113119
if (grepl("b", sides)) {
114120
rugs$x_b <- segmentsGrob(

0 commit comments

Comments
 (0)