Darius
Darius

Reputation: 489

Graph with a shaded the area occupied by multiple lines

PROBLEM STATEMENT

My dataset contains 100 groups, each of one can be plotted as a line with a similar shape against a response variable. I would like to produce a graph where all the space taken by the 100 curved lines turns into a shaded area, so it is easier to show the variation of the response variable across all the groups. This will also allow to clearly see the values or intervals in the x-axis where the response variable has lower variation (shaded area will be narrower as most lines will overlap) or higher variation.

CODE EXAMPLE

library(tidyverse)
library(ggplot2)

set.seed(1)

# Produce a similar table to the real one
example <- tibble(values = seq(0, 10, 0.1),
                  sine1  = sin(values + 0.2),
                  sine2  = sin(values - 0.2),
                  sine3  = sin(values + 0.4) + 0.2,
                  sine4  = sin(values - 0.4) - 0.2,
                  sine5  = sin(values - 0.4) + 0.2,
                  sine6  = sin(values - 0.2) + 0.4) %>%
            pivot_longer(-values) # final format with 3 columns

# Create a line graph, where each line represents a different sine curve
graph1 <- ggplot(example, aes(x = values, y = value, col = name)) +
          geom_line(size = 3, show.legend = FALSE, alpha = 0.5) +
          theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
                panel.background = element_blank(), axis.line = element_line(colour = "black"))
graph1

QUESTION

Is there a way of going from this graph...

enter image description here

enter image description here

to this one (or similar)? Note: the thick black line is not strictly necessary enter image description here

Upvotes: 1

Views: 371

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173858

You just need to group per individual time unit and calculate the minimum / maximum values. This allows you to plot a geom_ribbon:

example %>% 
  group_by(values) %>% 
  summarize(min = min(value), max = max(value)) %>%
  ggplot() +
  geom_ribbon(aes(x = values, ymin = min, ymax = max), size = 2,
              fill = "#29c8e5", color = "black") +
  theme_classic()

enter image description here

If you would rather have the ribbon overlying your original plot, you could do:

ribbon <- example %>% 
  group_by(values) %>% 
  summarize(min = min(value), max = max(value))

graph1 +
  geom_ribbon(aes(x = values, ymin = min, ymax = max), 
              data = ribbon, size = 0, fill = "#29c8e5", 
              color = NA, alpha = 0.3, inherit.aes = FALSE)

enter image description here

For what it's worth, I think the first option is more visually striking.

Upvotes: 2

Related Questions