rggplot2legendlegend-properties

Separate out overlapping legend items ggplot()


The Issue

I have a plot that has various lines and symbols. They are all coloured by location ID. This has resulted in the legend items overlapping.

i.e.

enter image description here

There are four symbols: circle, triangle, diamond and square. I need to separate these out from the lines in the legend. To look something like this:

enter image description here

Plot Code

library(ggplot2)
library(ggh4x)         # for facet_wrap2() 

 cols <- c("#ADD8E6","#B4EDD2","#E86A92","#F6AE2D")

 p1 <- ggplot(test, aes(x=DateTime, y=mAODscale, colour=label2)) +
  geom_line() +
  geom_point(data=filter(test, minDate %in% 1), 
             mapping=aes(x=DateTime, y=mAODscale), 
             size=2.5, shape=17) +
  geom_point(data=filter(test, maxDate %in% 1), 
             mapping=aes(x=DateTime, y=mAODscale), 
             size=2.5, shape=16) +
  geom_point(data=filter(test, maxDate2 %in% 1), 
             mapping=aes(x=DateTime, y=mAODscale), 
             size=2.5, shape=18) +
  geom_point(data=filter(test, noMaxDate2 %in% 1), 
             mapping=aes(x=DateTime, y=mAODscale), 
             size=2.5, shape=15) +
  scale_colour_manual(name="", values=cols) +
  facet_wrap2(~fourLoc, ncol=2)
      

Test Data Frame

structure(list(label2 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), levels = c("B1", "B2", "CH1", 
"CH3"), class = "factor"), DateTime = structure(c(-61781702325, 
-61750166325, -61718630325, -61687094325, -61781702325, -61750166325, 
-61718630325, -61687094325, -61781702325, -61750166325, -61718630325, 
-61687094325, -61781702325, -61750166325, -61718630325, -61687094325
), class = c("POSIXct", "POSIXt"), tzone = ""), fourLoc = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("control", 
"test"), class = "factor"), mAODscale = c(0.57, 0.03, 0.24, 0.15, 
0.47, 0.68, 0.55, 0.75, 0.65, 0.62, 0.77, 0.99, 0.98, 0.12, 0.4, 
0.99), minDate = c(0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 
0L, 0L, 1L, 0L, 0L), maxDate = c(1L, 0L, 0L, 0L, 0L, 1L, 0L, 
0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), maxDate2 = c(0L, 0L, 0L, 
0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L), noMaxDate2 = c(0L, 
0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), row.names = c(NA, 
-16L), class = "data.frame")

Solution

  • You need to create a variable with the different types (maxDate, maxDate2, ...) that you can map to the shape argument in the aes of geom_point. You can do this when you create a long format of your data (and filter for the relevant entries) with pivot_longer:

    
    test <- structure(list(label2 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L,2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), 
                                              levels = c("B1", "B2", "CH1", "CH3"), class = "factor"), 
                           DateTime = structure(c(-61781702325,-61750166325, -61718630325, -61687094325, -61781702325, -61750166325, 
                                                  -61718630325, -61687094325, -61781702325, -61750166325, -61718630325, 
                                                  -61687094325, -61781702325, -61750166325, -61718630325, -61687094325), 
                                                class = c("POSIXct", "POSIXt"), tzone = ""), 
                           fourLoc = structure(c(2L,2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), 
                                               levels = c("control", "test"), class = "factor"), 
                           mAODscale = c(0.57, 0.03, 0.24, 0.15,0.47, 0.68, 0.55, 0.75, 0.65, 0.62, 0.77, 0.99, 0.98, 0.12, 0.4,0.99), 
                           minDate = c(0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L), 
                           maxDate = c(1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L), 
                           maxDate2 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L), 
                           noMaxDate2 = c(0L,0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), 
                      row.names = c(NA,-16L), class = "data.frame")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
    library(tidyr)
    library(ggplot2)
    library(dplyr)
    
    test_long <- test %>% 
      pivot_longer(
        cols = minDate:noMaxDate2,
        names_to = "variable",
        values_to = "value"
      ) %>% 
      filter(value == 1)
    
    
    cols <- c("#ADD8E6","#B4EDD2","#E86A92","#F6AE2D")
    
    ggplot(test, aes(x=DateTime, y=mAODscale, colour=label2)) +
      geom_line() +
      geom_point(data = test_long, aes(x = DateTime, y = mAODscale, shape = variable, group = label2)) +
      scale_colour_manual(name="", values=cols)
    

    Created on 2023-08-30 by the reprex package (v1.0.0)