Reputation: 1945
I have the following data
,
# Generate Data
library(tidyverse)
library(ggspectra)
fake_data <- tibble(
time = seq(1,100, length.out = 1000),
gdp = time+time*(1-sin(0.15*time))
) %>% mutate(
time = row_number(),
growth = (gdp - lag(gdp))/lag(gdp) * 100,
peak = as.numeric(near(gdp, peaks(gdp), tol = 0.01)),
valley = as.numeric(near(gdp, valleys(gdp), tol = 0.01)),
type = as.factor(
case_when(
gdp >= lag(gdp) ~ "Expansion",
gdp <= lag(gdp) ~ "Contraction"
)
)
) %>% mutate(
cycle = as.factor(cumsum(peak + valley))
) %>% na.omit()
And I'm using ggplot2
to produce a plot
fake_data %>%
ggplot(mapping = aes(x = time, y = gdp)) +
geom_line() + geom_point(
fake_data %>% filter(peak == 1 | valley == 1),
mapping = aes(x = time, y = gdp)
) + geom_ribbon(aes(ymax = gdp, ymin = 0,fill = type, group = type), alpha = 0.5)
Which generates the following plot
,
Ideally, the contraction
and expansion
are clearly seperated for illustrative purposes. I attempted to create an additional group
to seperate the connected ribbons
but I got the following error Error: Aesthetics can not vary with a ribbon
.
How do I generate this plot neatly?
Upvotes: 0
Views: 147
Reputation: 37933
You might benefit from setting your groups from run-length based IDs. The data.table::rleid()
can help with that.
library(tidyverse)
library(ggspectra)
fake_data <- tibble(
time = seq(1,100, length.out = 1000),
gdp = time+time*(1-sin(0.15*time))
) %>% mutate(
time = row_number(),
growth = (gdp - lag(gdp))/lag(gdp) * 100,
peak = as.numeric(near(gdp, peaks(gdp), tol = 0.01)),
valley = as.numeric(near(gdp, valleys(gdp), tol = 0.01)),
type = as.factor(
case_when(
gdp >= lag(gdp) ~ "Expansion",
gdp <= lag(gdp) ~ "Contraction"
)
)
) %>% mutate(
cycle = as.factor(cumsum(peak + valley))
) %>% na.omit()
fake_data %>%
ggplot(mapping = aes(x = time, y = gdp)) +
geom_line() +
geom_point(
fake_data %>% filter(peak == 1 | valley == 1),
mapping = aes(x = time, y = gdp)
) +
geom_area(aes(fill = type, group = data.table::rleid(type)),
alpha = 0.5)
Created on 2021-08-27 by the reprex package (v1.0.0)
Upvotes: 1