Plotting one daily time serie per year in R (ggplot2)

Similar to this question: Split up time series per year for plotting which has done in Python, I want to display the daily time series as multiple lines by year. How can I achieve this in R?

library(ggplot2)
library(dplyr)

# Dummy data
df <- data.frame(
  day = as.Date("2017-06-14") - 0:364,
  value = runif(365) + seq(-140, 224)^2 / 10000
)

# Most basic bubble plot
p <- ggplot(df, aes(x=day, y=value)) +
  geom_line() + 
  xlab("")
p

Out:

enter image description here

One solution is using ggplot2, but date_labels are displayed incorrectly:

library(tidyverse)
library(lubridate)
p <- df %>% 
  # mutate(date = ymd(date)) %>% 
  mutate(date=as.Date(date)) %>% 
  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")

# Raw daily data
p + geom_line()

Out:

enter image description here

Alternative solution is to use gg_season from feasts package:

library(feasts)
library(tsibble)
library(dplyr)
tsibbledata::aus_retail %>%
  filter(
    State == "Victoria",
    Industry == "Cafes, restaurants and catering services"
  ) %>%
  gg_season(Turnover)

Out:

enter image description here

References:

Split up time series per year for plotting

R – How to create a seasonal plot – Different lines for years

>Solution :

If you want your x axis to represent the months from January to February, then perhaps getting the yday of the date and adding it to the first of January on a random year would be simplest:

library(tidyverse)
library(lubridate)

df <- data.frame(
  day = as.Date("2017-06-14") - 0:364,
  value = runif(365) + seq(-140, 224)^2 / 10000
)

df %>% 
  mutate(year = factor(year(day)), date = yday(day) + as.Date('2017-01-01')) %>% 
  ggplot(aes(date, value, color = year)) +
  geom_line() +
  scale_x_date(breaks = seq(as.Date('2017-01-01'), by = 'month', length = 12),
               date_labels = '%b')

Created on 2023-02-07 with reprex v2.0.2

Leave a Reply