rggplot2geom-vline

ggplot with both `geom_vline` and `geom_hline`. Task: need separate legends


library(tidyverse)
library(lubridate)

y <- rnorm(100)

df <- tibble(y) %>% 
  mutate(os = factor(rep_len(1:5, 100)),
         date = seq(from = ymd('2013-01-01'), by = 1, length.out = 100))

ggplot(df, aes(x = date, y = y, colour = os)) +
  geom_line() +
  geom_vline(
    aes(xintercept = min(date), linetype = 'os 1'), 
    colour = 'red') +
  geom_vline(
    aes(xintercept = median(date), linetype = 'os 2'), 
    colour = 'blue') +
  geom_hline(
    aes(yintercept = 1, linetype = "dashed"),
    colour = "black"
  ) +
  scale_linetype_manual(
    name = 'lines',
    values = c('os 1' = 1, 'os 2' = 1),
    guide = guide_legend(override.aes = list(colour = c('red', 'blue')))) 

output:

enter image description here

What is wrong with output:

  1. The geom_hline is missing.
  2. The legend combines the vline and the hline to form a cross.

Correct output:

  1. THe geom_hline should be drawn.
  2. Need a separate legend for the vlines and hlines. i.e., lines in the vline legend should be vertical while lines in the hline legend should be horizontal.

Solution

  • This could be achieved by

    1. Adding the hline to scale_linetype_manual
    2. Making use of a custom key glyph as in this answer.
    library(tidyverse)
    library(lubridate)
    
    set.seed(123)
    
    y <- rnorm(100)
    
    df <- tibble(y) %>% 
      mutate(os = factor(rep_len(1:5, 100)),
             date = seq(from = ymd('2013-01-01'), by = 1, length.out = 100))
    
    draw_key_cust <- function(data, params, size) {
      if (data$colour %in% c("red", "blue"))
        draw_key_vpath(data, params, size)
      else
        draw_key_path(data, params, size)
    }
    
    ggplot(df, aes(x = date, y = y, colour = os)) +
      geom_line() +
      geom_vline(
        aes(xintercept = min(date), linetype = 'os 1'), 
        colour = 'red', key_glyph = "cust") +
      geom_vline(
        aes(xintercept = median(date), linetype = 'os 2'), 
        colour = 'blue', key_glyph = "cust") +
      geom_hline(
        aes(yintercept = 1, linetype = "dashed"), 
        colour = "black", key_glyph = "cust"
      ) +
      scale_linetype_manual(
        name = 'lines',
        values = c('os 1' = 1, 'os 2' = 1, dashed = 2),
        guide = guide_legend(override.aes = list(colour = c('red', 'blue', 'black'))))