0

So the idea is simple, and I guess the solution lies somewhere, but I just cannot find it. I have 3 yearly time series, with daily values, and I'd like to be able to display all 3 years in the same graph, where the x coordinates are the months, and the y coordinates the values for each year.

Philippe Grondier
  • 10,900
  • 3
  • 33
  • 72
  • basic plot or ggplot? – D.J Sep 07 '20 at 14:07
  • any would do! I guess once I get the concept, I can look for it in other plotting tools – Philippe Grondier Sep 07 '20 at 14:22
  • Duplicates: [ggplot year by year comparison](https://stackoverflow.com/questions/13520639/ggplot-year-by-year-comparison); [plot data with different dates](https://stackoverflow.com/questions/17364435/plot-data-with-different-dates); [ggplot: Multiple years on same plot by month](https://stackoverflow.com/questions/41206181/ggplot-multiple-years-on-same-plot-by-month); [R - How to create a seasonal plot - Different lines for years](https://stackoverflow.com/questions/48722758/r-how-to-create-a-seasonal-plot-different-lines-for-years) – Henrik Sep 07 '20 at 14:37

3 Answers3

3

I would suggest a ggplot2 approach to your consideration using dummy data. If you want months in x-axis you can 'hack' the date assigning a new year so that you can see the months in the axis after formating with scale_x_date(). You also have to exatract the years from your date in order to add the colors. Here the code:

library(ggplot2)
library(dplyr)
set.seed(123)
#Dummy data
df <- data.frame(Date=c(seq(as.Date('2017-01-01'),
                          as.Date('2017-12-31'),
                          length.out = 365),
                        seq(as.Date('2018-01-01'),
                            as.Date('2018-12-31'),
                            length.out = 365),
                        seq(as.Date('2019-01-01'),
                            as.Date('2019-12-31'),
                            length.out = 365)),
                 value=rnorm(1095,5,2))
#Format
#Create months and years
df %>% mutate(Year=format(Date,'%Y'),
              Date2=as.Date(paste0('2020-',format(Date,'%m-%d')))) %>%
  ggplot(aes(x=Date2,y=value,group=Year,color=Year))+
  geom_line()+
  scale_x_date(date_labels="%B",breaks = '1 month')

Output:

enter image description here

Update: Also credits to great @AllanCameron, here a nicer solution using cumsum() for the variable value:

#Dummy data
df <- data.frame(Date=c(seq(as.Date('2017-01-01'),
                          as.Date('2017-12-31'),
                          length.out = 365),
                        seq(as.Date('2018-01-01'),
                            as.Date('2018-12-31'),
                            length.out = 365),
                        seq(as.Date('2019-01-01'),
                            as.Date('2019-12-31'),
                            length.out = 365)),
                 value = c(replicate(3, cumsum(rnorm(365)))))
#Format
#Create months and years
df %>% mutate(Year=format(Date,'%Y'),
              Date2=as.Date(paste0('2020-',format(Date,'%m-%d')))) %>%
  ggplot(aes(x=Date2,y=value,group=Year,color=Year))+
  geom_line()+
  scale_x_date(date_labels="%B",breaks = '1 month')

Output:

enter image description here

Duck
  • 39,058
  • 13
  • 42
  • 84
  • 1
    I would have a very similar approach here Duck (+1), though for illustration you would get a nicer plot with `value = c(replicate(3, cumsum(rnorm(365))))` – Allan Cameron Sep 07 '20 at 14:23
  • @AllanCameron Dr. Cameron, you are right! I will update the solution with your helpful suggestion now ! – Duck Sep 07 '20 at 14:25
  • Thanks for all these interesting answers! So we are saying here that there is no "straight forward" way, and we have to create a fake and common time line to be able to superimpose multiple time series. – Philippe Grondier Sep 07 '20 at 14:40
  • @PhilippeGrondier not quite. You could use the `yday` function from lubridate to get the day of each year from 1:365, then use that as your x-axis. To get the months labelled correctly you would do `scale_x_continuous(breaks = c(1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335), labels = month.abb)` – Allan Cameron Sep 07 '20 at 14:45
  • @PhilippeGrondier It depends on your data! It is also possible to extract all day-month values from dates and plot in x-axis as factor! As AllanCameron said there are also other ways! – Duck Sep 07 '20 at 14:46
2

Here's an example using @Duck's data (with a different random seed) to show that it is possible to plot the three time series without faking the years, just plugging the dates and values into ggplot and using a couple of lubridate functions:

ggplot(df, aes(x = lubridate::yday(Date), 
               y = value, 
               color = factor(lubridate::year(Date)))) +
geom_line() +
scale_x_continuous(
  breaks = lubridate::yday(seq(as.Date("2017-01-01"), 
                               by = "1 month", length.out = 12)), 
  labels = month.abb) +
  labs(x = "Date", colour = "Year")

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
0

in a regular plot it would look something like this:

#x11() # opens a graphics window
plot(mtcars$drat, type="l")
lines(mtcars$wt, col=2) # permits extra lines to be added to an already existing plot
points(mtcars$gear, col=3) # permits points added to an already existing plot

although if you have a dedicated time variable it would change like so:

x11()
plot(mtcars$date, mtcars$drat, type="l")
lines(mtcars$date, mtcars$wt, col=2)
lines(mtcars$date, mtcars$gear, col=3)

as mtcars doesn't have a timeline, this is not a valid example but the idea behind it works

D.J
  • 1,180
  • 1
  • 8
  • 17
  • Here you are just superimposing two time series with the same dates. My issue is with the superimposition of two time series relating to different years: I have a 2018, 2019 and 2020 series, and I want to display the 3 of them on one "Jan to Dec" x-axis – Philippe Grondier Sep 07 '20 at 14:25
  • ah, i see. i thought it would work as there shouldn't be a difference between years except for leap-years like 2020. i think you would still be able to do this while changing the date in the lines()/points() command - i have not tried that though. still i think @Duck 's answer is much better and more comprehensive so admittedly i'd go with that. i just wanted to give a non-ggplot answer as it can be faster for prototyping plots – D.J Sep 07 '20 at 14:36