Question Details

No question body available.

Tags

r ggplot2 geom-ribbon

Answers (2)

Accepted Answer Available
Accepted Answer
July 9, 2026 Score: 3 Rep: 13,385 Quality: Expert Completeness: 80%

I like Allans answer, adding data in between is a good approach. I thought of M--s continuous area approach. Maybe you can introduce a ribboncolor to fill the ribbon by - allthough that creates auroras at the edges, it shows the "'changing' between dates" at the first of June, where there's only one data point.

library(ggplot2)

df as.Date(format="%Y-%m-%d"), temp
min = c(19, 19, 20, 21, 22, 23, 22, 21, 21, 19, 19, 19, 21, 21, 23, 23, 22, 22, 20, 19), tempmean = c(20, 20, 21, 22, 23, 24, 23, 22, 22, 20, 20, 20, 22, 22, 24, 24, 23, 23, 21, 20), tempmax = c(21, 21, 22, 23, 24, 25, 24, 23, 23, 21, 21, 21, 23, 23, 25, 25, 24, 24, 22, 21), shade22 = c(NA, NA, NA, 21, 22, NA, 22, 21, NA, NA, NA, NA, 21, 21, NA, NA, 22, 22, NA, NA), shade24 = c(NA, NA, NA, NA, NA, 23, NA, NA, NA, NA, NA, NA, NA, NA, 23, 23, NA, NA, NA, NA) ) |> transform( ribboncolor = dplyr::casewhen( !is.na(shade22) ~ "red", !is.na(shade24)~ "maroon", .default = NAcharacter ) ) datebreaks Global Options -> General -> Graphics-Tab -> Backend = "AGG"
July 9, 2026 Score: 4 Rep: 179,041 Quality: Medium Completeness: 80%

There's no way round telling geomribbon where you want it to start and end. Of course, that information is already available in your data, but you will need to duplicate some of the rows and use conditional logic to get the correct values for shade22 into them.

Note that this code contains a line to convert sampledate into a Date column because your sample data frame has it as a character column.

library(dplyr)

bindrows(lapply(1:4, \(x) df)) %>% mutate(sampledate = as.Date(sampledate)) %>% arrange(site, sampledate) %>% mutate(stepup = is.na(shade22) & !is.na(lag(shade22)) & !is.na(lead(shade24)), stepdown = is.na(shade22) & !is.na(lead(shade22)) & !is.na(shade24)) %>% mutate(shade22 = ifelse(stepup | stepdown, shade24, shade22)) %>% filter(!duplicated(.)) %>% select(-c(stepup, stepdown)) %>% ggplot(aes(x = sampledate, y = tempmean, group = site)) + geomribbon(aes(x = sampledate, ymax = tempmax, ymin = tempmin), alpha = 0.5, fill = "orange") + geompath(aes(y = tempmean), linetype = "solid", color = "black") + geomhline(yintercept = 22, linetype = "dashed", color = "red") + geomhline(yintercept = 24, linetype = "dashed", color = "maroon") + geomribbon(aes(ymax = shade22, ymin = 18), fill="red", alpha = 0.4, na.rm = TRUE) + geomribbon(aes(ymax = shade24, ymin = 18), fill = "maroon", alpha = 0.4, na.rm = TRUE) + scaleycontinuous("Soil temperature (°C)", limits = c(18, 25)) + scalexdate("Month", breaks = datebreaks, labels = scales::dateformat("%b"), datebreaks = "1 month") + theme(axis.text.x = elementtext(angle = 90, hjust = 1)) + facetwrap(vars(site), ncol = 1, strip.position = "right")

enter image description here