Common date scale with year as aesthetic

27 views
Skip to first unread message

Sam Albers

unread,
Oct 1, 2015, 3:54:45 PM10/1/15
to ggplot2
Hello all,

Apologies in advance if this is more of a lubridate question. I would
like to plot a time series using ggplot2 mapping the year to a colour
aesthetic. That is easy to do by extracting the year as a factor rom a
Date object then mapping it to colour. However, I still have the year
information left in the Date object so that ggplot2 plots all values
from 1910 to 1912. But what I would like to do is plot these multiple
years of data on a common year scale (i.e. January-December) so that
points on the same day are plotted on the same vertical space. I am
not expecting the example below to do this but I thought this would be
a good starting point to ask this question. Can anyone suggest a good
way to accomplish this?

library(ggplot2)
library(lubridate)

df<-data.frame(Date=seq(as.Date("1910/1/1"), as.Date("1912/1/1"), "days"),
v1=rnorm(731)
)

df$year<-factor(year(df$Date))

ggplot(df, aes(x=Date, y=v1, colour=year)) +
geom_point()


Thanks in advance.

Sam

Doug Mitarotonda

unread,
Oct 1, 2015, 4:10:23 PM10/1/15
to Sam Albers, ggplot2
So you want the x-axis to be Jan to Dec and plot values by day? My first thought is you just map all of the data to a baseline year (perhaps one that was a leap year so you don’t have issues in Feb) but retain the actual year column before doing that so you can map color on it. This does not seem like a very elegant solution, but would get the job done.
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Dennis Murphy

unread,
Oct 2, 2015, 1:58:37 AM10/2/15
to Sam Albers, ggplot2
You may have leap year issues if your series spans one or more of
them, but a simple fix is to use the yday() function from lubridate
which returns the day of the year. This isn't an ideal solution with
respect to the date labels, but here is one way to operationalize
Doug's suggestion in your example after getting rid of the orphan
observation in 2012:

library(ggplot2)
library(lubridate)
library(dplyr)

df <- data.frame(Date=seq(as.Date("1910/1/1"), as.Date("1911/12/31"), "days"),
v1=rnorm(730))

df <- df %>% mutate(year = factor(year(Date)),
doy = yday(Date))

# Comment out the legend repositioning if you don't like it
# Labels are positioned at the 15th of each month - see below for details
ggplot(df, aes(x = doy, y = v1, color = year)) +
geom_point() + geom_line() +
scale_x_continuous(breaks = yday(as.Date(paste(2011, 1:12, 15, sep = "-"))),
labels = month.abb) +
theme(legend.position = c(1, 1), legend.justification = c(1, 1)) +
xlab("Day of year")

You didn't specify whether you wanted the tick marks at the beginning,
middle or end of the month, so I opted for the 15th as a compromise:

yday(as.Date(paste(2011, 1:12, 15, sep = "-")))

Change the day to position the tick marks at whichever day of month
you desire. month.abb is a vector of three-character month labels,
which is very convenient for requests like these.


Dennis
Reply all
Reply to author
Forward
0 new messages