Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting a scale_x_continuous axis with quarterly data

Tags:

r

ggplot2

I have a data set of counted things, in two groups, aggregated to quarterly counts. The Date_Qtr variable was derived from a larger data set with lubridate. The data frame is as follows.

dat = structure(list(Group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("TypeA", 
"TypeB"), class = "factor"), Date_Qtr = c(2011.1, 2011.2, 2011.3, 
2011.4, 2012.1, 2012.2, 2012.3, 2012.4, 2013.1, 2013.2, 2013.3, 
2013.4, 2014.1, 2014.2, 2014.3, 2014.4, 2015.1, 2015.2, 2011.1, 
2011.2, 2011.3, 2011.4, 2012.1, 2012.2, 2012.3, 2012.4, 2013.1, 
2013.2, 2013.3, 2013.4, 2014.1, 2014.2, 2014.3, 2014.4, 2015.1, 
2015.2), Counts = c(105L, 82L, 72L, 79L, 93L, 118L, 81L, 96L, 
84L, 83L, 84L, 81L, 99L, 103L, 111L, 80L, 127L, 107L, 54L, 51L, 
64L, 64L, 53L, 65L, 78L, 63L, 92L, 61L, 80L, 71L, 88L, 66L, 67L, 
57L, 75L, 59L)), .Names = c("Group", "Date_Qtr", "Counts"), class = "data.frame", row.names = c(NA, 
-36L))

I have plotted a time series in ggplot2 as follows, with the Date_Qtr variable as a scale_x_continuous. Formerly, when I plotted monthly data it was easy to assign breaks at quartely intervals.

ggplot(dat, aes(x = Date_Qtr, y = Counts)) + 
  geom_point( aes( color = Group ), size = 3) + 
  geom_line(aes(color = Group), size = 0.8) +
  scale_y_continuous("Number of things", 
                     limits = c(0, 150)) +
  scale_x_continuous("Year and quarter when things were counted") +
  theme_bw() + 
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5),
        legend.title = element_blank(),
        legend.position = c(0.4, 0.85))

Is it possible, with a continuous scale, to represent the data as the actual quarters for each data point, preferably in a format "Jan-Mar 2012" etc.

Thanks in advance.

like image 529
John Avatar asked Jul 03 '15 03:07

John


2 Answers

You could use Dates for the x-axis:

library(ggplot2)
library(scales)
library(zoo)

make_date <- function(x) {
  year <- floor(x)
  x <- year + (x - year)/0.4 - 0.125
  as.Date(as.yearqtr(x))
}

format_quarters <- function(x) {
  x <- as.yearqtr(x)
  year <- as.integer(x)
  quart <- as.integer(format(x, "%q"))

  paste(c("Jan-Mar","Apr-Jun","Jul-Sep","Oct-Dec")[quart], 
        year)
}


ggplot(dat, aes(x = make_date(Date_Qtr), y = Counts)) + 
  geom_point( aes( color = Group ), size=3) + 
  geom_line(aes(color = Group), size=0.8) +
  scale_y_continuous("Number of things", 
                     limits=c(0,150)) +
  scale_x_date("Year and quarter when things were counted",
                     breaks = date_breaks("3 months"),
                     labels = format_quarters) +
  theme_bw() + 
  theme(axis.text.x = element_text(angle=45, vjust = 0.5),
        legend.title=element_blank(),
        legend.position = c(.4,0.85))

resulting plot

like image 127
Roland Avatar answered Sep 21 '22 23:09

Roland


You can get the labels you want by adding a labels argument to scale_x_continuous.

Another issue is that Date_Qtr uses 0.1, 0.2, 0.3, and 0.4 for the quarters, so the quarters aren't numerically in the right location within each year on the x-axis. To fix this, I added a Date_Qtr_New column with the quarters spaced properly.

I also moved the axis titles to a separate labs statement, just to reduce clutter.

# Create new date-quarter values representing actual numerical distance in time
dat$Date_Qtr_New = floor(dat$Date_Qtr) + (as.numeric(gsub(".*\\.([1-4])","\\1", dat$Date_Qtr)) - 1) * 0.25

ggplot(dat, aes(x = Date_Qtr_New, y = Counts)) + 
  geom_point( aes( color = Group ), size=3) + 
  geom_line(aes(color = Group), size=0.8) +
  scale_y_continuous(limits=c(0,150)) +
  # Set quarterly breaks and use labels argument to get the labels we want
  scale_x_continuous(breaks=seq(2011,2016.75,0.25), 
                     labels=paste(c("Jan-Mar","Apr-Jun","Jul-Sep","Oct-Dec"), 
                                  rep(2011:2016,each=4))) +
  labs(x="Year and quarter when things were counted",
       y="Number of things") +
  theme_bw() + 
  theme(axis.text.x = element_text(angle=45, vjust = 0.5),
        legend.title=element_blank(),
        legend.position = c(.4,0.85))

enter image description here

like image 43
eipi10 Avatar answered Sep 20 '22 23:09

eipi10