1
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 = 'black', key_glyph = "cust") +
  geom_hline(
    aes(yintercept = 1, linetype = "dashed"), 
    colour = "blue", key_glyph = "cust"
  ) +
  geom_hline(
    aes(yintercept = -1, linetype = "dashed 2"), 
    colour = "purple", key_glyph = "cust"
  ) +

  scale_linetype_manual(
    name = 'lines',
    values = c(2, 2, 1, 1),
    guide = guide_legend(override.aes = list(colour = c('red', 'black', 'blue', "purple")))) 

output:

enter image description here

In the legend, the 2 vertical lines are supposed to be on top while the 2 horizontal lines are supposed to be on the bottom.

How to control that?

  • You can explicitly set `breaks = c("dashed", "os 1", "dashed 2", "os 1")` in the linetype scale. – teunbrand Sep 22 '21 at 20:51
  • Legend key order can be a reason to pass a named vector of values to `values` in a manual scale function a la `values = c("os 1" = 2, "os 2" = 2, "dashed" = 1, "dashed 2" = 1)`. – aosmith Sep 22 '21 at 20:53
  • @aosmith that did not work. it did reorder the labels, but the linetypes are still uncontrollable, v, h, v, h. it should be v, v, h, h – Bear Bile Farming is Torture Sep 22 '21 at 20:58
  • @teunbrand that did not work – Bear Bile Farming is Torture Sep 22 '21 at 20:59
  • I think the v, h, v, h is because of your `draw_key()` function, where you put a vertical line if the color is red or blue. I switched that to red and black to match your plot and thought things looked fine: `if (data$colour %in% c("red", "black"))` – aosmith Sep 23 '21 at 01:16

1 Answers1

1

Part of the solution regarding the order of keys was here. The default order is alphabetic, but you can set the order using limits, and you can use pairs to define the corresponding linetype in values (otherwise it gets confusing with the re-ordering).

However, I have no solution yet to change the vertical/horizontal layout of the keys. There is a possible solution here, which shows that specific key aspects can be changed by applying grid::editGrob to the ggplot object, but it looks a bit daunting.

library(tidyverse)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

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 = 'black', key_glyph = "cust") +
  geom_hline(
    aes(yintercept = 1, linetype = "dashed"), 
    colour = "blue", key_glyph = "cust"
  ) +
  geom_hline(
    aes(yintercept = -1, linetype = "dashed 2"), 
    colour = "purple", key_glyph = "cust"
  ) +
  scale_linetype_manual(
    name = 'lines',
    values = c("os 1" = 1,
               "os 2" = 1,
               "dashed" = 2,
               "dashed 2" = 2),
    limits = c("os 1","os 2", "dashed", "dashed 2"),
    guide = guide_legend(override.aes = list(colour = c('red', 'black', 'blue', "purple")))) 

Created on 2021-09-22 by the reprex package (v2.0.1)

scrameri
  • 667
  • 2
  • 12
  • that's not the desired outcome. the legend is supposed to display in order v, v, h, h. what you have is v, h, v, h – Bear Bile Farming is Torture Sep 22 '21 at 21:13
  • I know, but at least the labels and colours are in the correct order? using `limits` is key here I think. The error ist just in the key line orientation, not in the order of keys, right? I couldn't figure this one out, sorry! – scrameri Sep 22 '21 at 21:16
  • Just saw that to solve the orientation of lines in the key, you might have to use `grid` editing functions, but it looks quite complicated: https://stackoverflow.com/questions/42954248/how-to-change-the-orientation-of-the-key-of-a-legend-in-ggplot. Good luck! – scrameri Sep 22 '21 at 21:24