Seasonal Analysis

Author

Rami Krispin

Published

July 3, 2025

Seasonality is a structural pattern of time series data, which is derived from periodic fluctuations of the series. Most of the seasonal patterns in nature are related to the Earth spinning around the Sun. For example, the demand for electricity is high during the daytime and very low past midnight. Similarly, the demand for natural gas is high during the wintertime and low during the summer.

Time series can be categorized into one of the following three buckets:

In this section, we will use a simple seasonal plot to explore seasonality.

Load the Libraries and Data

library(dplyr)
library(plotly)
library(tsibble)

load(file = "./data/ts.RData")

Create a Seasonal Plot

head(ts2)
# A tsibble: 6 x 4 [1M]
     index date             y series_id
     <mth> <date>       <int> <chr>    
1 2001 Jan 2001-01-01 2505011 NUS      
2 2001 Feb 2001-02-01 2156873 NUS      
3 2001 Mar 2001-03-01 2086568 NUS      
4 2001 Apr 2001-04-01 1663832 NUS      
5 2001 May 2001-05-01 1385163 NUS      
6 2001 Jun 2001-06-01 1313119 NUS      

Let’s reformat the data:

ts2 <- ts2 |>
dplyr::mutate(month = lubridate::month(date), 
month_label = lubridate::month(date, label = TRUE),
year = lubridate::year(date)) |>
dplyr::arrange(date)

ts2
# A tsibble: 292 x 7 [1M]
      index date             y series_id month month_label  year
      <mth> <date>       <int> <chr>     <dbl> <ord>       <dbl>
 1 2001 Jan 2001-01-01 2505011 NUS           1 Jan          2001
 2 2001 Feb 2001-02-01 2156873 NUS           2 Feb          2001
 3 2001 Mar 2001-03-01 2086568 NUS           3 Mar          2001
 4 2001 Apr 2001-04-01 1663832 NUS           4 Apr          2001
 5 2001 May 2001-05-01 1385163 NUS           5 May          2001
 6 2001 Jun 2001-06-01 1313119 NUS           6 Jun          2001
 7 2001 Jul 2001-07-01 1459919 NUS           7 Jul          2001
 8 2001 Aug 2001-08-01 1528483 NUS           8 Aug          2001
 9 2001 Sep 2001-09-01 1360871 NUS           9 Sep          2001
10 2001 Oct 2001-10-01 1507428 NUS          10 Oct          2001
# ℹ 282 more rows
years <- unique(ts2$year)

colors <- colorRampPalette(RColorBrewer::brewer.pal(9, "YlGnBu"))(length(years))


p <- plot_ly()

for (i in seq_along(years)) {
  year_data <- ts2 |> filter(year == years[i])
  
  p <- p |>
    add_trace(
      data = year_data,
      x = ~month_label,
      y = ~y,
      type = 'scatter',
      mode = 'lines+markers',
      name = as.character(years[i]),
      line = list(color = colors[i]),
      marker = list(color = colors[i])
    )
}


p