2

I have the following simple MWE. I want the green line in my legend to be a vertical line. Once I enable show.legend in geom_vline, it also adds a vertical line to every other line in the legend. Does anyone have a hint on how I can achieve this?

library(ggplot2)
ggplot(data = df) +
  geom_line(aes(x = a, y = b, colour = "one", linetype = "one"), size = 2) +
  geom_line(aes(x = a, y = c, colour = "two", linetype = "two"), size = 2) +
  geom_vline(aes(xintercept = 0.5, colour = "three", linetype = "three"), alpha = 1, show.legend = F) +
  scale_colour_manual("",
                      breaks = c("one", "two", "three"),
                      values = c("blue", "red", "green")) +
  scale_linetype_manual("",
                        breaks = c("one", "two", "three"),
                        values = c("dashed", "solid", "solid")) +
  theme_bw() +
  theme(legend.key.size = unit(2, "cm"),
        legend.position = c(0.05, 0.995), legend.justification = c(0.05, 0.995))

enter image description here

salomon
  • 281
  • 1
  • 6

1 Answers1

2

Adapting this answer one option to achieve your desired result would be to make use of a custom key glyph function. One drawback of this approach is that it conditions on the color of the line to choose between a horizontal or vertical line, i.e. that means that if you change the colors you have to adjust the condition too.

EDIT To get right line sizes in the legend there are two options. One would be to set the sizes in the custom key glyph function. A second option would be to set the size via the override.aes argument of guide_legend using guides(linetype = guide_legend(override.aes = list(size = c(2, 2, .5))))

library(ggplot2)

# Custom Key Glyph. Vertical Line if color = "green". Horizontal Line otherwise
draw_key_cust <- function(data, params, size) {
  if (data$colour == "green") {
    data$size <- .5
    draw_key_vpath(data, params, size)
  } else {
    data$size <- 2
    draw_key_path(data, params, size)
  }
}

ggplot(data = df) +
  geom_line(aes(x = a, y = b, colour = "one", linetype = "one"), size = 2, key_glyph = "cust") +
  geom_line(aes(x = a, y = c, colour = "two", linetype = "two"), size = 2, key_glyph = "cust") +
  geom_vline(aes(xintercept = 0.5, colour = "three", linetype = "three"), alpha = 1, key_glyph = "cust") +
  scale_colour_manual(breaks = c("one", "two", "three"),
                      values = c("blue", "red", "green")) +
  scale_linetype_manual(breaks = c("one", "two", "three"),
                        values = c("dashed", "solid", "solid")) +
  labs(color = NULL, linetype = NULL) +
  theme_bw() +
  theme(legend.key.size = unit(2, "cm"),
        legend.position = c(0.05, 0.995), 
        legend.justification = c(0.05, 0.995))

DATA

set.seed(42)
df <- data.frame(
  a = runif(100),
  b = runif(100),
  c = runif(100)
)
stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thanks, this works almost perfectly for my case. The only little thing that bothers me is that it also draws very small lines in the blue legend between the big lines. Any ideas how to fix this? – salomon Sep 05 '21 at 20:34
  • Hi @salomon. I just added an edit to fix this issue. Best S. – stefan Sep 05 '21 at 21:49
  • Excellent solution @stefan! For anyone else that stumbles upon this answer, there are several key_glyphs you can use and adapt at https://github.com/tidyverse/ggplot2/blob/0e64d9c56ccc8db31971723810c3c10f0a67d9e4/R/legend-draw.r – jared_mamrot May 31 '22 at 03:48
  • @jared_mamrot Thanks Jared. Great that you added the link to source code as a reference. Best S. – stefan May 31 '22 at 11:30