ggplot2 Time Series Heatmaps
[This article was first published on MarginTale, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
How do you easily get beautiful calendar heatmaps of time series in ggplot2? E.g:Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
![]() |
From MarginTale |
How do you attack the problem? Looking at the example output above:
- We facet_grid by “months” and “years”
- The data itself is plotted by “week of month” and “day of week” and coloured according to the value of interest
So, given a time series we just have to fiddle with time indexes to create a data.frame containing the time series as well as per observation the corresponding “month”, “year”, “week of month”, “day of week”. The rest is then a one-liner of code with Hadley’s wonderful ggplot2 system.
The following code contains step by step comments:
The following code contains step by step comments:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require(quantmod) | |
require(ggplot2) | |
require(reshape2) | |
require(plyr) | |
require(scales) | |
# Download some Data, e.g. the CBOE VIX | |
getSymbols("^VIX",src="yahoo") | |
# Make a dataframe | |
dat<-data.frame(date=index(VIX),VIX) | |
# We will facet by year ~ month, and each subgraph will | |
# show week-of-month versus weekday | |
# the year is simple | |
dat$year<-as.numeric(as.POSIXlt(dat$date)$year+1900) | |
# the month too | |
dat$month<-as.numeric(as.POSIXlt(dat$date)$mon+1) | |
# but turn months into ordered facors to control the appearance/ordering in the presentation | |
dat$monthf<-factor(dat$month,levels=as.character(1:12),labels=c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"),ordered=TRUE) | |
# the day of week is again easily found | |
dat$weekday = as.POSIXlt(dat$date)$wday | |
# again turn into factors to control appearance/abbreviation and ordering | |
# I use the reverse function rev here to order the week top down in the graph | |
# you can cut it out to reverse week order | |
dat$weekdayf<-factor(dat$weekday,levels=rev(1:7),labels=rev(c("Mon","Tue","Wed","Thu","Fri","Sat","Sun")),ordered=TRUE) | |
# the monthweek part is a bit trickier | |
# first a factor which cuts the data into month chunks | |
dat$yearmonth<-as.yearmon(dat$date) | |
dat$yearmonthf<-factor(dat$yearmonth) | |
# then find the "week of year" for each day | |
dat$week <- as.numeric(format(dat$date,"%W")) | |
# and now for each monthblock we normalize the week to start at 1 | |
dat<-ddply(dat,.(yearmonthf),transform,monthweek=1+week-min(week)) | |
# Now for the plot | |
P<- ggplot(dat, aes(monthweek, weekdayf, fill = VIX.Close)) + | |
geom_tile(colour = "white") + facet_grid(year~monthf) + scale_fill_gradient(low="red", high="yellow") + | |
opts(title = "Time-Series Calendar Heatmap") + xlab("Week of Month") + ylab("") | |
P |
It should be easy to wrap into a function and I hope its useful.
To leave a comment for the author, please follow the link and comment on their blog: MarginTale.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.