3

I am trying to plot a line segment with an arrow on the end, and make it appear in the legend. I can do this with the following code:

library(ggplot2)

# sample data
dat <- data.frame(
  x = as.factor(1:10),
  y = c(20,30,13,37,12,50,31,2,40,30),
  z = rep('a', 10)
)

# basic plot
ggplot(dat) +
  geom_segment(
    aes(x = x, xend = x, y = 0, yend = y+15, linetype = z), 
    arrow = arrow(length = unit(0.25, 'cm'), type = 'closed'),
    size = 0.7
  ) 

output:

enter image description here

issue:

My issue is that the arrow in the legend is not solidly filled like the plot is. I have tried using guide_legend(override.aes = aes(fill='black')) and guide_legend(override.aes = aes(type='closed')) but neither had any effect on the legend.

Does anyone know how to make the triangle be filled in and solidly black?

edit:

I have a similar issue with geom_label not including the black line around the label in the legend. I managed to get around this by adding a geom_rect in the exact position I want, but hopefully that's not the best solution :P

Any solution to either would be very helpful!

enter image description here

morgan121
  • 2,213
  • 1
  • 15
  • 33
  • apparently this is a known bug: https://github.com/tidyverse/ggplot2/issues/3455. Hopefully resolved in the next update – morgan121 Jul 25 '19 at 12:04

1 Answers1

6

Since ggplot2 3.2.0, it is possible to provide custom legend drawing functions. Thus, if a legend doesn't quite look right, you can always copy the respective legend drawing function from the ggplot2 code base and then modify as desired.

library(ggplot2)
library(grid)
library(rlang)

# legend drawing function, copied from ggplot2
draw_key_segment_custom <- function(data, params, size) {
  if (is.null(data$linetype)) {
    data$linetype <- 0
  } else {
    data$linetype[is.na(data$linetype)] <- 0
  }

  segmentsGrob(0.1, 0.5, 0.9, 0.5,
    gp = gpar(
      col = alpha(data$colour %||% data$fill %||% "black", data$alpha),
      # the following line was added relative to the ggplot2 code
      fill = alpha(data$colour %||% data$fill %||% "black", data$alpha),
      lwd = (data$size %||% 0.5) * .pt,
      lty = data$linetype %||% 1,
      lineend = "butt"
    ),
    arrow = params$arrow
  )
}


# sample data
dat <- data.frame(
  x = as.factor(1:10),
  y = c(20,30,13,37,12,50,31,2,40,30),
  z = rep('a', 10)
)

# basic plot
ggplot(dat) +
  geom_segment(
    aes(x = x, xend = x, y = 0, yend = y+15, linetype = z), 
    arrow = arrow(length = unit(0.25, 'cm'), type = 'closed'),
    size = 0.7,
    key_glyph = "segment_custom"
  ) 

Created on 2019-07-25 by the reprex package (v0.3.0)

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104