From 0e0602f998064f0fd34ca1186e7c4200205c81a5 Mon Sep 17 00:00:00 2001 From: Ax3man Date: Mon, 15 May 2017 11:40:34 +0200 Subject: [PATCH 1/3] Added linejoin parameter to geom_segment (#774). --- NEWS.md | 2 ++ R/geom-segment.r | 21 +++++++++++++++++++-- man/geom_segment.Rd | 18 +++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 703e265c05..70b6b64c70 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 2.2.1.9000 +* `geom_segment` now also takes a `linejoin` parameter. This allows more control over the appearance of the segments, which is especially useful for plotting thick arrows (@Ax3man, #774). + * `geom_smooth` now orders by the `x` aesthetic, making it easier to pass pre-computed values without manual ordering (@izahn, #2028). diff --git a/R/geom-segment.r b/R/geom-segment.r index 4f81e27577..6d4c614b33 100644 --- a/R/geom-segment.r +++ b/R/geom-segment.r @@ -15,6 +15,7 @@ #' @inheritParams geom_point #' @param arrow specification for arrow heads, as created by arrow(). #' @param lineend Line end style (round, butt, square). +#' @param linejoin Line join style (round, mitre, bevel). #' @seealso \code{\link{geom_path}} and \code{\link{geom_line}} for multi- #' segment lines and paths. #' @seealso \code{\link{geom_spoke}} for a segment parameterised by a location @@ -42,6 +43,19 @@ #' arrow = arrow(length = unit(0.1,"cm"))) + #' borders("state") #' +#' # Use lineend and linejoin to change the style of the segments +#' df2 <- expand.grid(lineend = c('round', 'butt', 'square'), +#' linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) +#' segments <- lapply(seq_len(nrow(df2)), function(i) { +#' annotate(geom = 'segment', x = 1, y = i, xend = 2, yend = i, size = 5, +#' lineend = df2$lineend[i], linejoin = df2$linejoin[i], arrow = arrow(type = "closed")) +#' }) +#' ggplot() + +#' segments + +#' geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), +#' hjust = 'outside', nudge_x = 0.2) + +#' xlim(1, 2.25) +#' #' # You can also use geom_segment to recreate plot(type = "h") : #' counts <- as.data.frame(table(x = rpois(100,5))) #' counts$x <- as.numeric(as.character(counts$x)) @@ -54,6 +68,7 @@ geom_segment <- function(mapping = NULL, data = NULL, ..., arrow = NULL, lineend = "butt", + linejoin = "round", na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { @@ -68,6 +83,7 @@ geom_segment <- function(mapping = NULL, data = NULL, params = list( arrow = arrow, lineend = lineend, + linejoin = linejoin, na.rm = na.rm, ... ) @@ -84,7 +100,7 @@ GeomSegment <- ggproto("GeomSegment", Geom, default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), draw_panel = function(data, panel_params, coord, arrow = NULL, - lineend = "butt", na.rm = FALSE) { + lineend = "butt", linejoin = "round", na.rm = FALSE) { data <- remove_missing(data, na.rm = na.rm, c("x", "y", "xend", "yend", "linetype", "size", "shape"), @@ -100,7 +116,8 @@ GeomSegment <- ggproto("GeomSegment", Geom, fill = alpha(coord$colour, coord$alpha), lwd = coord$size * .pt, lty = coord$linetype, - lineend = lineend + lineend = lineend, + linejoin = linejoin ), arrow = arrow )) diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index bef93262c7..987cfefe77 100644 --- a/man/geom_segment.Rd +++ b/man/geom_segment.Rd @@ -7,7 +7,8 @@ \usage{ geom_segment(mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., arrow = NULL, lineend = "butt", - na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) + linejoin = "round", na.rm = FALSE, show.legend = NA, + inherit.aes = TRUE) geom_curve(mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., curvature = 0.5, angle = 90, ncp = 5, @@ -49,6 +50,8 @@ to the paired geom/stat.} \item{lineend}{Line end style (round, butt, square).} +\item{linejoin}{Line join style (round, mitre, bevel).} + \item{na.rm}{If \code{FALSE}, the default, missing values are removed with a warning. If \code{TRUE}, missing values are silently removed.} @@ -111,6 +114,19 @@ ggplot(seals, aes(long, lat)) + arrow = arrow(length = unit(0.1,"cm"))) + borders("state") +# Use lineend and linejoin to change the style of the segments +df2 <- expand.grid(lineend = c('round', 'butt', 'square'), + linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) +segments <- lapply(seq_len(nrow(df2)), function(i) { + annotate(geom = 'segment', x = 1, y = i, xend = 2, yend = i, size = 5, + lineend = df2$lineend[i], linejoin = df2$linejoin[i], arrow = arrow(type = "closed")) +}) +ggplot() + + segments + + geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), + hjust = 'outside', nudge_x = 0.2) + + xlim(1, 2.25) + # You can also use geom_segment to recreate plot(type = "h") : counts <- as.data.frame(table(x = rpois(100,5))) counts$x <- as.numeric(as.character(counts$x)) From 927b7bcc2c1c01eb90851c6ca33ba40ebb8aa901 Mon Sep 17 00:00:00 2001 From: Ax3man Date: Thu, 1 Jun 2017 14:48:32 +0200 Subject: [PATCH 2/3] Simplify example code. --- R/geom-segment.r | 9 ++++----- man/geom_segment.Rd | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/R/geom-segment.r b/R/geom-segment.r index 6d4c614b33..78d28e9f02 100644 --- a/R/geom-segment.r +++ b/R/geom-segment.r @@ -46,12 +46,11 @@ #' # Use lineend and linejoin to change the style of the segments #' df2 <- expand.grid(lineend = c('round', 'butt', 'square'), #' linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) -#' segments <- lapply(seq_len(nrow(df2)), function(i) { -#' annotate(geom = 'segment', x = 1, y = i, xend = 2, yend = i, size = 5, -#' lineend = df2$lineend[i], linejoin = df2$linejoin[i], arrow = arrow(type = "closed")) -#' }) +#' df2 <- data.frame(df2, y = 1:9) #' ggplot() + -#' segments + +#' geom_segment(aes(x = 1, y = y, xend = 2, yend = y), df2, size = 4, +#' lineend = df2$lineend, linejoin = df2$linejoin, +#' arrow = arrow(length = unit(0.5, "inches"))) + #' geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), #' hjust = 'outside', nudge_x = 0.2) + #' xlim(1, 2.25) diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index 987cfefe77..d01dc012e4 100644 --- a/man/geom_segment.Rd +++ b/man/geom_segment.Rd @@ -117,12 +117,11 @@ ggplot(seals, aes(long, lat)) + # Use lineend and linejoin to change the style of the segments df2 <- expand.grid(lineend = c('round', 'butt', 'square'), linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) -segments <- lapply(seq_len(nrow(df2)), function(i) { - annotate(geom = 'segment', x = 1, y = i, xend = 2, yend = i, size = 5, - lineend = df2$lineend[i], linejoin = df2$linejoin[i], arrow = arrow(type = "closed")) -}) +df2 <- data.frame(df2, y = 1:9) ggplot() + - segments + + geom_segment(aes(x = 1, y = y, xend = 2, yend = y), df2, size = 4, + lineend = df2$lineend, linejoin = df2$linejoin, + arrow = arrow(length = unit(0.5, "inches"))) + geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), hjust = 'outside', nudge_x = 0.2) + xlim(1, 2.25) From c184b57c456b005271f5fb3d9d4171239307786a Mon Sep 17 00:00:00 2001 From: Ax3man Date: Thu, 1 Jun 2017 16:55:42 +0200 Subject: [PATCH 3/3] Changed indentation and moved data and aes to ggplot --- R/geom-segment.r | 21 ++++++++++++--------- man/geom_segment.Rd | 21 ++++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/R/geom-segment.r b/R/geom-segment.r index 78d28e9f02..86507efb62 100644 --- a/R/geom-segment.r +++ b/R/geom-segment.r @@ -44,16 +44,19 @@ #' borders("state") #' #' # Use lineend and linejoin to change the style of the segments -#' df2 <- expand.grid(lineend = c('round', 'butt', 'square'), -#' linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) +#' df2 <- expand.grid( +#' lineend = c('round', 'butt', 'square'), +#' linejoin = c('round', 'mitre', 'bevel'), +#' stringsAsFactors = FALSE +#' ) #' df2 <- data.frame(df2, y = 1:9) -#' ggplot() + -#' geom_segment(aes(x = 1, y = y, xend = 2, yend = y), df2, size = 4, -#' lineend = df2$lineend, linejoin = df2$linejoin, -#' arrow = arrow(length = unit(0.5, "inches"))) + -#' geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), -#' hjust = 'outside', nudge_x = 0.2) + -#' xlim(1, 2.25) +#' ggplot(df2, aes(x = 1, y = y, xend = 2, yend = y, label = paste(lineend, linejoin))) + +#' geom_segment( +#' lineend = df2$lineend, linejoin = df2$linejoin, +#' size = 3, arrow = arrow(length = unit(0.3, "inches")) +#' ) + +#' geom_text(hjust = 'outside', nudge_x = -0.2) + +#' xlim(0.5, 2) #' #' # You can also use geom_segment to recreate plot(type = "h") : #' counts <- as.data.frame(table(x = rpois(100,5))) diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index d01dc012e4..b84d1d25b6 100644 --- a/man/geom_segment.Rd +++ b/man/geom_segment.Rd @@ -115,16 +115,19 @@ ggplot(seals, aes(long, lat)) + borders("state") # Use lineend and linejoin to change the style of the segments -df2 <- expand.grid(lineend = c('round', 'butt', 'square'), - linejoin = c('round', 'mitre', 'bevel'), stringsAsFactors = FALSE) +df2 <- expand.grid( + lineend = c('round', 'butt', 'square'), + linejoin = c('round', 'mitre', 'bevel'), + stringsAsFactors = FALSE +) df2 <- data.frame(df2, y = 1:9) -ggplot() + - geom_segment(aes(x = 1, y = y, xend = 2, yend = y), df2, size = 4, - lineend = df2$lineend, linejoin = df2$linejoin, - arrow = arrow(length = unit(0.5, "inches"))) + - geom_text(aes(x = 2, y = 1:9, label = paste(df2$lineend, df2$linejoin)), - hjust = 'outside', nudge_x = 0.2) + - xlim(1, 2.25) +ggplot(df2, aes(x = 1, y = y, xend = 2, yend = y, label = paste(lineend, linejoin))) + + geom_segment( + lineend = df2$lineend, linejoin = df2$linejoin, + size = 3, arrow = arrow(length = unit(0.3, "inches")) + ) + + geom_text(hjust = 'outside', nudge_x = -0.2) + + xlim(0.5, 2) # You can also use geom_segment to recreate plot(type = "h") : counts <- as.data.frame(table(x = rpois(100,5)))