3

I want to shade the area between the grouped lines. I've tried different approaches but I don't manage to do it.

df <- data.frame(year = rep(c(1950:1955), each = 2),
                 gender = factor(rep(c("male", "female"), times = 6)),
                 value = c(40526812, 37450509, 43027405,
                            40135682, 45801088, 43130369,
                            48579427, 46077640, 50948574,
                            48493786, 53052094, 50537984))

df |> 
  ggplot(aes(year, value, group = gender)) +
  geom_line()

enter image description here

Thanks in advance!

PabloAB
  • 233
  • 1
  • 6
  • 2
    Does this answer your question? [Shade region between two lines with ggplot](https://stackoverflow.com/questions/28586635/shade-region-between-two-lines-with-ggplot) – Adam Quek Jul 22 '22 at 10:10

2 Answers2

4

You could define the boundaries of the area by using a pivot_wider to create the ymax and ymin of the area in geom_ribbon so you don't need to subset per argument. So it will be easier to reproduce. Here an example:

df <- data.frame(year = rep(c(1950:1955), each = 2),
                 gender = factor(rep(c("male", "female"), times = 6)),
                 value = c(40526812, 37450509, 43027405,
                           40135682, 45801088, 43130369,
                           48579427, 46077640, 50948574,
                           48493786, 53052094, 50537984))

library(ggplot2)
library(dplyr)
library(tidyr)
area <- df %>%
  pivot_wider(names_from = gender, values_from = value) %>%
  mutate(
    ymax = pmax(male, female),
    ymin = pmin(male, female)
  )

ggplot(data = df, mapping = aes(year, y = value, group = gender)) +
  geom_line() +
  geom_ribbon(data = area, mapping = aes(year, ymin = ymin, ymax = ymax), alpha = 0.4, inherit.aes = FALSE ) 

Created on 2022-07-22 by the reprex package (v2.0.1)

Quinten
  • 35,235
  • 5
  • 20
  • 53
  • 2
    I find this solution brilliant. Thanks!! – PabloAB Jul 22 '22 at 10:36
  • What does inherit.aes does? I've never used it. – PabloAB Jul 22 '22 at 11:09
  • 2
    When inherit.aes if FALSE, it overrides the default aesthetics instead of combining them. This is useful because we use in this case two dataframes so we can define both the data and aesthetics so that is does not inherit the behaviour. – Quinten Jul 22 '22 at 11:13
3

You can use geom_ribon which allows to shade areas within axis values.
A stronger alpha will play on the shader intensity.

  ggplot(data=df, aes(year, value, group = gender)) +
  geom_line() + 
  geom_ribbon(data=subset(df, 1950 <= year & year <= 1955), 
              aes(ymin=rep(subset(df, gender=='female')$value, each=2), 
                  ymax=rep(subset(df, gender=='male')$value, each=2)), fill="blue", alpha=0.5)

enter image description here

Yacine Hajji
  • 1,124
  • 1
  • 3
  • 20