Search code examples
rggplot2linelegend

Legend ggplot interaction different colours and line types


I've tried all day to get a line plot with different line colours and types but now that I managed that, the legend doesn't appear anymore.

The first 10 (of 100) rows of the dataframe:

    Duration   Clouds         1        2        3         4         5         6          7         8
1   15.00000 51.56604  3.319234 7.479382 6.185313  5.620474 30.149642  5.075788   6.145367  4.779686
2   15.30303 51.56604  3.389524 7.437142 6.146534  5.730071 29.224362  5.127665   6.321472  4.831718
3   15.60606 51.56604  3.461303 7.395140 6.107999  5.841805 28.327479  5.180072   6.502624  4.884316
4   15.90909 51.56604  3.534602 7.353375 6.069705  5.955718 27.458121  5.233015   6.688967  4.937487
5   16.21212 51.56604  3.609453 7.311846 6.031652  6.071852 26.615443  5.286498   6.880650  4.991237
6   16.51515 51.56604  3.685889 7.270552 5.993836  6.190251 25.798626  5.340529   7.077825  5.045572
7   16.81818 51.56604  3.763944 7.229491 5.956258  6.310959 25.006878  5.395111   7.280651  5.100498
8   17.12121 51.56604  3.843652 7.188662 5.918916  6.434020 24.239427  5.450252   7.489290  5.156022
9   17.42424 51.56604  3.925048 7.148063 5.881807  6.559481 23.495530  5.505956   7.703907  5.212151
10  17.72727 51.56604  4.008168 7.107694 5.844932  6.687388 22.774462  5.562229   7.924675  5.268891

And my script to get the plot:

> plot.interact1.2 <- ggplot(pred_df2, aes(x=Duration)) + 
+   geom_line(aes(y = `1`), color="#D8C033") + 
+   geom_line(aes(y = `2`), color="#B9A2A3") +
+   geom_line(aes(y = `3`), color="#225F6D") +
+   geom_line(aes(y = `4`), color="#B0946F") +
+   geom_line(aes(y = `5`), color="#D8C033", linetype="dashed") +
+   geom_line(aes(y = `6`), color="#B9A2A3", linetype="dashed") +
+   geom_line(aes(y = `7`), color="#225F6D", linetype="dashed") +
+   geom_line(aes(y = `8`), color="#B0946F", linetype="dashed") +
+   scale_color_discrete(name = "Lunar phase", labels = c("New Moon", "Full Moon")) +
+   theme_ipsum() +
+   ylab("Predicted mean values") +
+   xlab("Survey duration")
> plot.interact1.2

Interaction plot

I got the scale_color_discrete() as a solution to a similar question from a different post here on stackoverflow but it doesn't seem to help in my situation.


Solution

  • Try this approach, and follow the advice of @markus and @RichardTelford. The key to have a legend is reshaping data to long. That can be done with pivot_longer(). Then add the necessary elements to the plot. Here the code:

    library(tidyverse)
    #Code
    df %>% pivot_longer(-c(Duration,Clouds)) %>%
      mutate(name=gsub('X','',name)) %>%
      ggplot(aes(x=Duration,y=value,color=name,group=name,linetype=name))+
      geom_line()+
      scale_color_manual(values=c("#D8C033","#B9A2A3","#225F6D","#B0946F",
                                  "#D8C033","#B9A2A3","#225F6D","#B0946F"))+
      scale_linetype_manual(values=c(rep('solid',4),rep('dashed',4)))+
      theme_bw() +
      ylab("Predicted mean values") +
      xlab("Survey duration")
    

    Output:

    enter image description here

    Some data used:

    #Data
    df <- structure(list(Duration = c(15, 15.30303, 15.60606, 15.90909, 
    16.21212, 16.51515, 16.81818, 17.12121, 17.42424, 17.72727), 
        Clouds = c(51.56604, 51.56604, 51.56604, 51.56604, 51.56604, 
        51.56604, 51.56604, 51.56604, 51.56604, 51.56604), X1 = c(3.319234, 
        3.389524, 3.461303, 3.534602, 3.609453, 3.685889, 3.763944, 
        3.843652, 3.925048, 4.008168), X2 = c(7.479382, 7.437142, 
        7.39514, 7.353375, 7.311846, 7.270552, 7.229491, 7.188662, 
        7.148063, 7.107694), X3 = c(6.185313, 6.146534, 6.107999, 
        6.069705, 6.031652, 5.993836, 5.956258, 5.918916, 5.881807, 
        5.844932), X4 = c(5.620474, 5.730071, 5.841805, 5.955718, 
        6.071852, 6.190251, 6.310959, 6.43402, 6.559481, 6.687388
        ), X5 = c(30.149642, 29.224362, 28.327479, 27.458121, 26.615443, 
        25.798626, 25.006878, 24.239427, 23.49553, 22.774462), X6 = c(5.075788, 
        5.127665, 5.180072, 5.233015, 5.286498, 5.340529, 5.395111, 
        5.450252, 5.505956, 5.562229), X7 = c(6.145367, 6.321472, 
        6.502624, 6.688967, 6.88065, 7.077825, 7.280651, 7.48929, 
        7.703907, 7.924675), X8 = c(4.779686, 4.831718, 4.884316, 
        4.937487, 4.991237, 5.045572, 5.100498, 5.156022, 5.212151, 
        5.268891)), class = "data.frame", row.names = c("1", "2", 
    "3", "4", "5", "6", "7", "8", "9", "10"))
    

    If you wanna change the labels in legends you can add labels to the scale_*_*() options like this:

    #Code 2
    df %>% pivot_longer(-c(Duration,Clouds)) %>%
      mutate(name=gsub('X','',name)) %>%
      ggplot(aes(x=Duration,y=value,color=name,group=name,linetype=name))+
      geom_line()+
      scale_color_manual(values=c("#D8C033","#B9A2A3","#225F6D","#B0946F",
                                  "#D8C033","#B9A2A3","#225F6D","#B0946F"),
                         labels=c('1'='Var1','2'='Var2','3'='Var3','4'='Var4',
                                  '5'='Var5','6'='Var6','7'='Var7','8'='Var8'))+
      scale_linetype_manual(values=c(rep('solid',4),rep('dashed',4)),
                            labels=c('1'='Var1','2'='Var2','3'='Var3','4'='Var4',
                                     '5'='Var5','6'='Var6','7'='Var7','8'='Var8'))+
      theme_bw() +
      ylab("Predicted mean values") +
      xlab("Survey duration")
    

    Output:

    enter image description here