GGPLOT2 Theme: FiveThirtyEight look-alike

Theme source: http://minimaxir.com/2015/02/ggplot-tutorial/

fte_theme <- function() {
  
  # Generate the colors for the chart procedurally with RColorBrewer
  palette <- brewer.pal("Greys", n=9)
  color.background = palette[2]
  color.grid.major = palette[3]
  color.axis.text = palette[6]
  color.axis.title = palette[7]
  color.title = palette[9]
  
  # Begin construction of chart
  theme_bw(base_size=15) +
    
    # Set the entire chart region to a light gray color
    theme(panel.background=element_rect(fill=color.background, color=color.background)) +
    theme(plot.background=element_rect(fill=color.background, color=color.background)) +
    theme(panel.border=element_rect(color=color.background)) +
    
    # Format the grid
    theme(panel.grid.major=element_line(color=color.grid.major, size=.05)) +
    theme(panel.grid.minor=element_blank()) +
    theme(axis.ticks=element_blank()) +
    
    # Format the legend, but hide by default
    theme(legend.background = element_rect(fill=color.background, size=.5, linetype="dotted")) +
    theme(legend.text = element_text(size=8,color="black")) +
    theme(legend.position = "top") +
    theme(legend.title=element_blank()) +
   
    
    # Set title and axis labels, and format these and tick marks
    theme(plot.title=element_text(color=color.title, size=20, vjust=4.25, face = "bold")) +
    theme(axis.text.x=element_text(size=14,color="black")) +
    theme(axis.text.y=element_text(size=12,color="black")) +
    theme(axis.title.x=element_text(size=14,color="black", face = "bold")) +
    theme(axis.title.y=element_text(size=14,color="black", vjust=1.25)) +
    
    # Plot margins
    theme(plot.margin = unit(c(0.35, 0.2, 0.3, 0.35), "cm"))
}

Calendar Heatmap

require(quantmod)
require(ggplot2)
require(reshape2)
require(plyr)
require(scales)
require(RColorBrewer)


getSymbols("CMG", src="yahoo")
## [1] "CMG"
# Make a dataframe
dat<-data.frame(date=index(CMG),CMG)

# 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))

#CHECK DATASET
head(dat)
##         date CMG.Open CMG.High CMG.Low CMG.Close CMG.Volume CMG.Adjusted
## 1 2007-01-03    56.90    56.95   56.00     56.41     519300        56.41
## 2 2007-01-04    56.50    56.50   55.13     55.38     471200        55.38
## 3 2007-01-05    55.58    55.68   54.61     55.00     508800        55.00
## 4 2007-01-08    55.01    56.20   54.80     56.05     286500        56.05
## 5 2007-01-09    56.04    57.39   56.04     56.45     571600        56.45
## 6 2007-01-10    55.73    56.65   55.51     56.21     869100        56.21
##   year month monthf weekday weekdayf yearmonth yearmonthf week monthweek
## 1 2007     1    Jan       3      Wed  Jan 2007   Jan 2007    1         1
## 2 2007     1    Jan       4      Thu  Jan 2007   Jan 2007    1         1
## 3 2007     1    Jan       5      Fri  Jan 2007   Jan 2007    1         1
## 4 2007     1    Jan       1      Mon  Jan 2007   Jan 2007    2         2
## 5 2007     1    Jan       2      Tue  Jan 2007   Jan 2007    2         2
## 6 2007     1    Jan       3      Wed  Jan 2007   Jan 2007    2         2
tail(dat)
##            date CMG.Open CMG.High CMG.Low CMG.Close CMG.Volume
## 2403 2016-07-19   413.91   419.65  413.00    415.31     909600
## 2404 2016-07-20   415.24   420.62  414.09    419.68     846900
## 2405 2016-07-21   419.68   420.16  412.42    418.07    1547400
## 2406 2016-07-22   414.65   444.13  412.19    442.48    4087200
## 2407 2016-07-25   443.00   443.50  435.00    441.52    1477300
## 2408 2016-07-26   431.95   439.24  429.85    430.85    1074500
##      CMG.Adjusted year month monthf weekday weekdayf yearmonth yearmonthf
## 2403       415.31 2016     7    Jul       2      Tue  Jul 2016   Jul 2016
## 2404       419.68 2016     7    Jul       3      Wed  Jul 2016   Jul 2016
## 2405       418.07 2016     7    Jul       4      Thu  Jul 2016   Jul 2016
## 2406       442.48 2016     7    Jul       5      Fri  Jul 2016   Jul 2016
## 2407       441.52 2016     7    Jul       1      Mon  Jul 2016   Jul 2016
## 2408       430.85 2016     7    Jul       2      Tue  Jul 2016   Jul 2016
##      week monthweek
## 2403   29         4
## 2404   29         4
## 2405   29         4
## 2406   29         4
## 2407   30         5
## 2408   30         5
#only use 2013 to 2016 data (inclusive) - 4 years
library(sqldf)

query = sqldf("SELECT * FROM dat WHERE year BETWEEN 2013 and 2016 ")
head(query)
##         date CMG.Open CMG.High CMG.Low CMG.Close CMG.Volume CMG.Adjusted
## 1 2013-01-02   304.26   306.73  298.31    301.06     491400       301.06
## 2 2013-01-03   297.00   305.08  295.13    300.95     473000       300.95
## 3 2013-01-04   301.44   304.28  300.13    300.18     368100       300.18
## 4 2013-01-07   299.96   301.00  295.35    299.59     385900       299.59
## 5 2013-01-08   300.35   301.50  295.43    297.76     368900       297.76
## 6 2013-01-09   298.45   299.57  292.18    294.03     442400       294.03
##   year month monthf weekday weekdayf yearmonth yearmonthf week monthweek
## 1 2013     1    Jan       3      Wed  Jan 2013   Jan 2013    0         1
## 2 2013     1    Jan       4      Thu  Jan 2013   Jan 2013    0         1
## 3 2013     1    Jan       5      Fri  Jan 2013   Jan 2013    0         1
## 4 2013     1    Jan       1      Mon  Jan 2013   Jan 2013    1         2
## 5 2013     1    Jan       2      Tue  Jan 2013   Jan 2013    1         2
## 6 2013     1    Jan       3      Wed  Jan 2013   Jan 2013    1         2
tail(query)
##           date CMG.Open CMG.High CMG.Low CMG.Close CMG.Volume CMG.Adjusted
## 893 2016-07-19   413.91   419.65  413.00    415.31     909600       415.31
## 894 2016-07-20   415.24   420.62  414.09    419.68     846900       419.68
## 895 2016-07-21   419.68   420.16  412.42    418.07    1547400       418.07
## 896 2016-07-22   414.65   444.13  412.19    442.48    4087200       442.48
## 897 2016-07-25   443.00   443.50  435.00    441.52    1477300       441.52
## 898 2016-07-26   431.95   439.24  429.85    430.85    1074500       430.85
##     year month monthf weekday weekdayf yearmonth yearmonthf week monthweek
## 893 2016     7    Jul       2      Tue  Jul 2016   Jul 2016   29         4
## 894 2016     7    Jul       3      Wed  Jul 2016   Jul 2016   29         4
## 895 2016     7    Jul       4      Thu  Jul 2016   Jul 2016   29         4
## 896 2016     7    Jul       5      Fri  Jul 2016   Jul 2016   29         4
## 897 2016     7    Jul       1      Mon  Jul 2016   Jul 2016   30         5
## 898 2016     7    Jul       2      Tue  Jul 2016   Jul 2016   30         5
# Now for the plot
P<- ggplot(query, aes(monthweek, weekdayf, fill = CMG.Close)) + 
  geom_tile(colour = "white") + facet_grid(year~monthf) + scale_fill_gradient(low="red", high="yellow") +
  ggtitle("Chipotle Mexican Grill Closing Price") +  xlab("\n\nWeek of Month") + ylab("") + fte_theme()
P