Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use different color scales for different geoms in ggplot

I can’t find a way to implement two different color scales for two different geoms in the same ggplot. I’ve tried three things: manually define two color scales, but that results in the second scale overpowering the first; define the second color scale as a variable, but that doesn’t work; use the argument fillwith that second scale, that doesn’t work either. So what’s the right way? I’d also be grateful if the plot would show two two legends: one for the first geom_segment and one for the second geom_segment

ggplot(data = df2, #%>% 
       #filter(MM == "aoi"), 
       aes(x = start_pm, xend = end_pm,
           y = MM_by, yend = MM_by,               
           color = MM_annotation)) +
  geom_segment(size = 3) +
  geom_point(aes(x = max_x, y = MM_by), alpha = 0) +  #plot invisible dummy end points
  scale_y_discrete(name = NULL, limits = rev) +         #rev to get A at the top
  facet_wrap(~ Utterance, scales = "free_x", ncol = 1) +
  scale_colour_manual(values = c("*" = "lemonchiffon",
                                 "A" = "darkorange",
                                 "B" = "lawngreen",
                                 "C" = "slateblue1")) +
  
  # add vertical lines demarcating word end points:
  geom_vline(data = df2 %>% 
               filter(MM == "word"),
             aes(xintercept = end_pm), lty = 3)+
  
  # add words:
  geom_text(data = df2 %>% 
              filter(MM == "word"),
            aes(x = end_pm -(end_pm - start_pm)/2, label = MM_annotation), size = 3, colour = "white")+
  
  # gesture:
  geom_segment(data = df2 %>%
                 filter(MM == "gesture") #%>% 
               #mutate(col = ifelse(MM_annotation == "prep", "skyblue",
               #                    ifelse(MM_annotation == "stroke", "royalblue",
               #                           ifelse(MM_annotation == "hold", "blue", "navyblue")))
               ,
               aes(x = start_pm, xend = end_pm,
                   y = MM_by, yend = MM_by,             
                   color = MM_annotation)) +
  scale_colour_manual(values = c("prep" = "lightblue",
                                 "stroke" = "royalblue",
                                 "hold" = "blue",
                                 "retract" = "navyblue"))

Data:

df2 <- structure(list(Utterance = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
                                              1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
                                              2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
                                              4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), levels = c("C: [what's] a !mountain! for you: (#1)", 
                                                                                              "NA: (0.554) (#1)", "C: ((v: laughs))= (#1)", "A: =I don't know the (Schauinsland) is a small mount[ain] (#1)"
                                              ), class = "factor"), MM_by = c("Gaze_by_A", "Gaze_by_A", "Gaze_by_A", 
                                                                              "Gaze_by_A", "Gaze_by_B", "Gaze_by_B", "Gaze_by_B", "Gaze_by_B", 
                                                                              "Gaze_by_B", "Gaze_by_C", "Words_by_C", "Words_by_C", "Words_by_C", 
                                                                              "Words_by_C", "Words_by_C", "Words_by_C", "Gesture_by_C", "Gesture_by_C", 
                                                                              "Gesture_by_C", "Gaze_by_A", "Gaze_by_A", "Gaze_by_B", "Gaze_by_C", 
                                                                              "Gesture_by_C", "Gesture_by_C", "Gaze_by_A", "Gaze_by_B", "Gaze_by_C", 
                                                                              "Gesture_by_C", "Gaze_by_A", "Gaze_by_A", "Gaze_by_B", "Gaze_by_B", 
                                                                              "Gaze_by_C", "Gaze_by_C", "Words_by_A", "Words_by_A", "Words_by_A", 
                                                                              "Words_by_A", "Words_by_A", "Words_by_A", "Words_by_A", "Words_by_A", 
                                                                              "Words_by_A", "Words_by_A", "Gesture_by_A", "Gesture_by_A"), 
                      MM = c("aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", "aoi", 
                             "aoi", "aoi", "word", "word", "word", "word", "word", "word", 
                             "gesture", "gesture", "gesture", "aoi", "aoi", "aoi", "aoi", 
                             "gesture", "gesture", "aoi", "aoi", "aoi", "gesture", "aoi", 
                             "aoi", "aoi", "aoi", "aoi", "aoi", "word", "word", "word", 
                             "word", "word", "word", "word", "word", "word", "word", "gesture", 
                             "gesture"), MM_annotation = c("*", "B", "*", "C", "A", "*", 
                                                           "C", "*", "A", "A", "what", "'s", "a", "mountain", "for", 
                                                           "you", "prep", "stroke", "hold", "C", "*", "A", "A", "hold", 
                                                           "retract", "*", "A", "A", "retract", "*", "C", "A", "*", 
                                                           "A", "*", "I", "do", "n't", "know", "the", "Schauinsland", 
                                                           "is", "a", "small", "mountain", "stroke", "retract"), start_pm = c(0, 
                                                                                                                              400, 867, 933, 0, 693, 940, 1413, 1560, 0, 0, 333, 447, 600, 
                                                                                                                              1113, 1333, 0, 547, 934, 1813, 2166, 1813, 1813, 1813, 2179, 
                                                                                                                              2367, 2367, 2367, 2367, 3437, 4437, 3437, 3743, 3437, 5737, 
                                                                                                                              3437, 3548, 3660, 3833, 4046, 4200, 4740, 4880, 5000, 5273, 
                                                                                                                              3437, 3950), end_pm = c(400, 867, 933, 1820, 693, 940, 1413, 
                                                                                                                                                      1560, 1820, 1820, 333, 447, 600, 1113, 1333, 1820, 547, 934, 
                                                                                                                                                      1813, 2166, 2373, 2380, 2380, 2179, 2366, 3427, 3427, 3427, 
                                                                                                                                                      3437, 4437, 6057, 3743, 6057, 5737, 6057, 3548, 3660, 3833, 
                                                                                                                                                      4046, 4200, 4740, 4880, 5000, 5273, 6055, 3950, 4104), max_x = c(2700, 
                                                                                                                                                                                                                       2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 
                                                                                                                                                                                                                       2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 4513, 4513, 
                                                                                                                                                                                                                       4513, 4513, 4513, 4513, 5067, 5067, 5067, 5067, 6137, 6137, 
                                                                                                                                                                                                                       6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 
                                                                                                                                                                                                                       6137, 6137, 6137, 6137, 6137, 6137)), row.names = c(NA, -47L
                                                                                                                                                                                                                       ), class = c("tbl_df", "tbl", "data.frame"))
  

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

As already mentioned in the comments an easy way to have multiple legends would be to use the ggnewscale package which allows for multiple scales and legends for the same aesthetic:

library(ggplot2)
library(dplyr, warn=FALSE)
library(ggnewscale)

ggplot(
  data = df2,
  aes(
    x = start_pm, xend = end_pm,
    y = MM_by, yend = MM_by,
    color = MM_annotation
  )
) +
  geom_segment(size = 3) +
  geom_point(aes(x = max_x, y = MM_by), alpha = 0) + # plot invisible dummy end points
  scale_y_discrete(name = NULL, limits = rev) + # rev to get A at the top
  facet_wrap(~Utterance, scales = "free_x", ncol = 1) +
  scale_colour_manual(values = c(
    "*" = "lemonchiffon",
    "A" = "darkorange",
    "B" = "lawngreen",
    "C" = "slateblue1"
  )) +
  # add vertical lines demarcating word end points:
  geom_vline(
    data = df2 %>%
      filter(MM == "word"),
    aes(xintercept = end_pm), lty = 3
  ) +
  # add words:
  geom_text(
    data = df2 %>%
      filter(MM == "word"),
    aes(x = end_pm - (end_pm - start_pm) / 2, label = MM_annotation), size = 3, colour = "white"
  ) +
  ggnewscale::new_scale_color() +
  geom_segment(
    data = df2 %>%
      filter(MM == "gesture"),
    aes(
      x = start_pm, xend = end_pm,
      y = MM_by, yend = MM_by,
      color = MM_annotation
    )
  ) +
  scale_colour_manual(values = c(
    "prep" = "lightblue",
    "stroke" = "royalblue",
    "hold" = "blue",
    "retract" = "navyblue"
  ))
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading