Home > Mobile >  How to stack partially matched time periods with geom_area (ggplot2)?
How to stack partially matched time periods with geom_area (ggplot2)?

Time:09-30

With the following example, I get a plot where the areas are not stacked. I would like to stack them. This should be a partial stack, intensity starting at 0.5, then reaching 0.8 where stacked, then reaching 0.3 at the end.

I assume that the position argument does not work as the start and end date are not the same.

  1. Am I missing an argument that could solve this issue? Or maybe another geom?
  2. Do I have to subset the data into days, to get the desired output. If so, how can I acheive that?

Thanks in advance,

# Library
library(tidyverse)
library(lubridate)

# Data
df <- tibble(date_debut = as_date(c("2022-09-28", "2022-10-05")),
       intensity = c(0.5, 0.3),
       duration = days(c(14, 10)),
       type = (c("a", "b")))

# Adjustment
df <- df %>%
  mutate(date_fin = date_debut   duration) %>%
  pivot_longer(cols = c(date_debut, date_fin),
               names_to = "date_type",
               values_to = "date") 

# Plot
df %>%
  ggplot(aes(x = date, y = intensity, fill = type)) 
  geom_area(position = "stack")

CodePudding user response:

This is a tough data wrangling problem. The area plots only stack where the points in the two series have the same x values. The following will achieve that, though it's quite a profligate approach.

df %>%
  mutate(interval = interval(date_debut, date_debut   duration)) %>%
  group_by(type) %>%
  summarize(time = seq(as.POSIXct(min(df$date_debut)), 
                       as.POSIXct(max(df$date_debut   df$duration)), by = 'min'),
            intensity = ifelse(time %within% interval, intensity, 0)) %>%
  ggplot(aes(x = time, y = intensity, fill = type))  
  geom_area(position = position_stack())

enter image description here

CodePudding user response:

Allan Cameron's answer inspired me to look further into complete.

The proposed answer was solving my question, so I accepted. However, it is indeed more complex than needed.

I solved it this way:

# Adjustment
df <- df %>%
  mutate(date_fin = date_debut   duration) %>% 
  group_by(type) %>% 
  complete(date_debut = seq(min(date_debut), max(date_fin), by = "1 day")) %>% 
  fill(intensity) %>% 
  select(date_debut, intensity, type)

ggplot(df, aes(x = date_debut, y = intensity, fill = type))  
  geom_area() 
  scale_x_date(date_labels = "%d",
               date_breaks = "1 day")

To avoid the weird empty space, it is fine for me to use geom_col (the question was about geom_area, so no worries).

ggplot(df, aes(x = date_debut, y = intensity, fill = type, colour = type))  
  geom_col(width = 0.95) 
  scale_x_date(date_labels = "%d",
               date_breaks = "1 day")
  • Related