Search code examples
rggplot2time-seriesggseasonplot

Seasonal plots for multiple variables using forecast::ggseasonplot


I'm trying to draw a seasonal plots for dataframe df, which contains time series data for 2 variables (value1 and value2):

df <- structure(list(date = structure(c(18292, 18321, 18352, 18382, 
18413, 18443, 18474, 18505, 18535, 18566, 18596, 18627, 18658, 
18686, 18717, 18747, 18778, 18808, 18839, 18870, 18900, 18931, 
18961, 18992), class = "Date"), value1 = c(-2.94, -40.61, -6.89, 
3.04, -3.5, 0.18, 6.79, 9.08, 9.35, 10.92, 20.53, 18.04, 24.6, 
154.6, 30.4, 32.1, 27.7, 32.1, 19.2, 25.4, 28, 26.9, 21.7, 20.9
), value2 = c(-12.66, 7.56, -1.36, -14.39, -16.18, 3.29, -0.69, 
-1.6, 13.47, 4.83, 4.56, 7.58, 28.7, 18.9, 39.1, 44, 52, 37.1, 
28.2, 32.7, 17.2, 20.4, 31.4, 19.5)), class = "data.frame", row.names = c(NA, 
-24L))

We could draw two time series in one plot using:

meltdf <- melt(df, id='date')
meltdf %>%
  ggplot(aes(x=date, y=value, colour=variable, group=variable)) +
        geom_point() +
        geom_line()

Out:

enter image description here

But I hope to use ggseasonplot to draw two plots for value1 and value2 seperately, each one will be similar to the following plot:

library(forecast)
ggseasonplot(AirPassengers, col=rainbow(12), year.labels=TRUE)

enter image description here

The problem I met is how to convert each subset dataframe to ts objects:

meltdf %>%
  filter(variable=='value1') %>% 
  as.ts() %>% 
  ggseasonplot(col=rainbow(12), year.labels=TRUE)

Thanks.

Update: implement with ggplot2 only:

meltdf %>% 
  filter(variable=='value2') %>% 
  select(-variable) %>% 
  mutate(
    year = factor(year(date)),     # use year to define separate curves
    date = update(date, year = 1)  # use a constant year for the x-axis
  ) %>% 
  ggplot(aes(date, value, color = year)) +
    scale_x_date(date_breaks = "1 month", date_labels = "%b")+
  geom_line()+
  geom_point()

enter image description here


Solution

  • This is what the feasts package is for -- handling time series graphics with multiple series in the same data frame. Here is how to do it with the sample data provided.

    library(tsibble)
    library(feasts)
    library(tidyr)
    library(dplyr)
    
    # Convert to tsibble object and plot using gg_season()
    df %>%
      pivot_longer(value1:value2) %>%
      mutate(date = yearmonth(date)) %>%
      as_tsibble(index = date, key = name) %>%
      gg_season(value)
    

    Created on 2022-02-14 by the reprex package (v2.0.1)

    See https://otexts.com/fpp3/seasonal-plots.html for more examples.