ggplot2 will not let me change the linetype to "longdash"

58 views Asked by At

I'm trying to make a plot with multiple different curves that each have a different linetype with ggplot2 and the lines always show up as solid.

I have tried using linetype = "longdash" and linetype = 6. I have also tried putting the linetype inside and outside the aes() and I've tried using scale_linetype_manual(). Nothing is working currently and every time I try to plot the data, it gives me a solid line. I have also tried updating ggplot2 using install.packages("ggplot2", dependencies = TRUE). I'll include my code below and the plot that I am trying to replicate.

ggplot(simu_dat, aes(tset)) +
  geom_line(aes(y = N.simu1), color="plum", linetype = 1, alpha=0.4, linewidth = 4) + 
  geom_line(aes(y = S.simu1), color="blue4", linetype = 1, alpha=0.4, linewidth = 4) + 
  geom_line(aes(y = I.simu1), color="deeppink", linetype = 1, alpha=0.4, linewidth = 4) + 
  geom_line(aes(y = R.simu1), color="springgreen", linetype = 1, alpha=0.4, linewidth = 4) +

  geom_line(aes(y = S.simu2), color="blue4", linetype = 6, linewidth = 2) + 
  geom_line(aes(y = I.simu2), color="deeppink", linetype = 6, linewidth = 2) + 
  geom_line(aes(y = R.simu2), color="springgreen", linetype = 6, linewidth = 2)

Here is the plot I'm trying to replicate

1

There are 1 answers

3
r2evans On

linetype=6 is "twodash", and linetype=5 is "longdash". You can look at vignette("ggplot2-specs", package="ggplot2") to see

An integer or name: 0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash, as shown below:

lty <- c("solid", "dashed", "dotted", "dotdash", "longdash", "twodash")
linetypes <- data.frame(
  y = seq_along(lty),
  lty = lty
) 
ggplot(linetypes, aes(0, y)) +
  geom_segment(aes(xend = 5, yend = y, linetype = lty)) + 
  scale_linetype_identity() + 
  geom_text(aes(label = lty), hjust = 0, nudge_y = 0.2) +
  scale_x_continuous(NULL, breaks = NULL) + 
  scale_y_reverse(NULL, breaks = NULL)

enter image description here

However, I suggest altering your code to work in a "long format". I don't have your data, but I think this is a good start for pivoting and adapting your code. (I'll show tidyr::pivot_longer, though this can be done about as easily with reshape2::melt and, with more work, stats::reshape.)

aesthestics <- tibble::tribble(
  ~ name, ~ color, ~ linetype, ~ linewidth, ~ alpha
  , "N.simu1", "plum", 1, 4, 0.4
  , "S.simu1", "blue4", 1, 4, 0.4
  , "I.simu1", "deeppink", 1, 4, 0.4
  , "R.simu1", "springgreen", 1, 4, 0.4
  , "S.simu2", "blue4", 5, 2, 1
  , "I.simu2", "deeppink", 5, 2, 1
  , "R.simu2", "springgreen", 5, 2, 1
)
pivot_longer(simu_dat, cols = -tset) |>
  # just in case, I don't know if you have more columns,
  # may not be necessary
  subset(name %in% aesthetics$name) |>
  ggplot(aes(tset, value)) +
  geom_line(aes(color = name, linetype = name, linewidth = name, alpha = name)) +
  scale_color_manual(values = setNames(aesthetics$color, aesthetics$name)) +
  scale_linetype_manual(values = setNames(aesthetics$linetype, aesthetics$name)) +
  scale_linewidth_manual(values = setNames(aesthetics$linewidth, aesthetics$name)) +
  scale_alpha_manual(values = setNames(aesthetics$alpha, aesthetics$name))

or slightly more broken-out

aes_ltrs <- tibble::tribble(
  ~ ltr, ~ color,
  , "N.simu1", "plum"
  , "S.simu1", "blue4"
  , "I.simu1", "deeppink"
  , "R.simu1", "springgreen"
  , "S.simu2", "blue4"
  , "I.simu2", "deeppink"
  , "R.simu2", "springgreen"
)
aes_sims <- tibble::tribble(
  ~ sim, ~ linetype, ~ linewidth, ~ alpha
  , "1", 1, 4, 0.4
  , "2", 5, 2, 1
)
dplyr::select(simu_dat, tset, matches("[NSIR]\\.simu[12]")) |>
  pivot_longer(cols = -tset, names_pattern = "([A-Z]+)\\.simu([0-9])",
               names_to = c("letter", "sim")) |>
  ggplot(aes(tset, value)) +
  geom_line(aes(group = ltr, color = ltr, linetype = sim, linewidth = sim, alpha = sim)) +
  scale_color_manual(values = setNames(aes_ltrs$color, aes_ltrs$ltr)) +
  scale_linetype_manual(values = setNames(aes_sims$linetype, aes_sims$sim)) +
  scale_linewidth_manual(values = setNames(aes_sims$linewidth, aes_sims$sim)) +
  scale_alpha_manual(values = setNames(aes_sims$alpha, aes_sims$sim))