0

I have a simple line graph which fluctuates around zero. Using geom_ribbon, I would like to color the area between the line and zero in two different colors, depending on whether the line is above or under zero. Using a single color to fill the area works:

geom_ribbon, single color

However, my attempt to fill the area in different colours (following this solution) fails as two seperate ribbons are created that either connect the points below or above zero.

df%>%
ggplot(aes(x=month, dif))+
geom_line()+
scale_x_date(date_breaks = "1 month", guide = guide_axis(angle = 90))+
geom_ribbon(aes(x=month, ymin=0, ymax=dif,  fill= dif>0), alpha=.5)+
scale_fill_manual(values=df$filler, name="fill")

enter image description here

Any suggestions on how this could be fixed?

Reproducible sample:

df<-structure(list(month = structure(c(17532, 17563, 17591, 17622, 
17652, 17683, 17713, 17744, 17775, 17805, 17836, 17866), class = "Date"), 
high = c(2618.74, 2453.39, 2075.89, 2535.89, 3331.15, 2238.85, 
3013.85, 3073.36, 2348.01, 3410.8, 653.56, 2840.22), low = c(3445.45, 
1352.91, 1594.51, 1344.27, 1676.73, 2410.76, 1289.4, 1330.72, 
1824.69, 1843.76, 1500.12, 3252.97), filler = c("red", "lightblue", 
"lightblue", "lightblue", "lightblue", "red", "lightblue", 
"lightblue", "lightblue", "lightblue", "red", "red"), dif = c(-826.71, 
1100.48, 481.38, 1191.62, 1654.42, -171.91, 1724.45, 1742.64, 
523.32, 1567.04, -846.56, -412.75)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -12L))
Rasul89
  • 588
  • 2
  • 5
  • 14
  • 1
    Here's a recent blog post with a helper function for this situation: https://www.nsgrantham.com/fill-between-two-lines-ggplot2 – Jon Spring Oct 17 '21 at 16:21
  • Does this answer your question? [How can I fill the space between values(geom\_line) and an intercept with ggplot2? Different Colors for values over and under intercept](https://stackoverflow.com/questions/44947806/how-can-i-fill-the-space-between-valuesgeom-line-and-an-intercept-with-ggplot2) – Miff Oct 17 '21 at 18:04

1 Answers1

1

I found a very clean solution using ggh4x package. Here it is

library(ggh4x)

ggplot(df, aes(x=month, y = dif)) +
  ggh4x::stat_difference(aes(ymin = 0, ymax = dif)) +
  geom_line(aes(y = dif)) +
  labs(fill = NULL)

enter image description here

UseR10085
  • 7,120
  • 3
  • 24
  • 54