Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

r

ggplot2

auc

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()
like image 886
ljh2001 Avatar asked Sep 03 '25 03:09

ljh2001


1 Answers

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

like image 57
Peter Avatar answered Sep 05 '25 02:09

Peter