Search code examples
rggplot2auc

How to shade region between two lines with differing endpoints with ggplot?


I have two lines of transect data taken during two scenarios. I am trying to highlight the area between the two curves created by the data but I have not found a solution using geom_ribbon(), likely due to the differing endpoints and measurement intervals. Any ideas?

Here is my data:

data <- structure(list(Distance = c(4L, 23L, 28L, 33L, 43L, 49L, 55L, 
62L, 69L, 75L, 78L, 83L, 89L, 95L, 102L, 109L, 118L, 125L, 133L, 
141L, 148L, 157L, 166L, 173L, 179L, 186L, 192L, 198L, 209L, 219L, 
230L, 242L, 253L, 265L, 277L, 288L, 298L, 307L, 0L, 10L, 20L, 
32L, 44L, 57L, 75L, 87L, 102L, 114L, 127L, 142L, 151L, 163L, 
176L, 186L, 194L, 206L, 216L, 230L, 244L, 256L, 269L, 277L, 286L, 
295L, 307L, 318L, 325L, 329L), Scenario = c("Min", "Min", "Min", 
"Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", 
"Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", 
"Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", 
"Min", "Min", "Min", "Min", "Min", "Min", "Min", "Min", "Gen", 
"Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", 
"Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", 
"Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", "Gen", 
"Gen", "Gen"), Depth = c(0, -5.4, -5.5, -5.8, -6.5, -7.4, -7.7, 
-7.6, -7.3, -7.3, -7.6, -7.4, -7.7, -7.9, -7.9, -7.7, -7.5, -7.4, 
-7, -6.3, -6, -5.6, -5.3, -5, -4.5, -3.6, -2.9, -2.2, -1.7, -2, 
-1.7, -1.7, -1.7, -1.2, -1.3, -1, -0.6, 0, 0, -7.2, -8.1, -9.2, 
-9.9, -9.7, -9.6, -10, -10.3, -10.5, -10.3, -9.9, -9.5, -9.1, 
-8.7, -8.2, -7.8, -7.2, -6.1, -5, -4.4, -4.4, -4.4, -4, -4.1, 
-3.8, -3.9, -3.5, -3.4, 0)), class = "data.frame", row.names = c(NA, 
-68L))

Here is the figure so far:

ggplot(data, aes(x = Distance, y = Depth, group = Scenario))+
  geom_line(aes(color = Scenario))+
  theme_bw()

Solution

  • A possible approach:

    1. using tidyr to separate out the two scenario groups
    2. geom_area to colour in the areas below the graphs, using white to overlay between y = 0 and the lower y value scenario.
    3. place panel grid lines back on top, done with help from Overlay grid rather than draw on top of it

    Note the order of ggplot arguments is important.

    library(ggplot2)
    library(tidyr)
    
    df1 <- 
      data |> 
      pivot_wider(names_from = "Scenario",
                  values_from = "Depth")
    
    ggplot(data)+
      geom_area(data = df1,
                aes(x = Distance,
                y = Gen),
                fill = "grey80")+
      geom_area(data = df1, 
                aes(x = Distance,
                    y = Min),
                fill = "white")+
      geom_line(aes(x = Distance, y = Depth, colour = Scenario))+
      theme_bw()+
      theme(panel.background = element_rect(fill = NA),
            panel.ontop = TRUE)
    
    

    Created on 2024-08-15 with reprex v2.0.2