3

This code produces a single boxplot:

df <- data.frame(value = rnorm(62), my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))

library(ggplot2)
ggplot(df, aes(as.Date(my.date), value)) + geom_boxplot() + scale_x_date(minor_breaks = "1 week", labels = date_format("%W\n%b"))

enter image description here

How can I produce a plot that has single boxplots for each week between 1 December and 31 January? So within the single plot, there should be about 8 boxplots. Would prefer solution that uses either ggplot() or scale_x_date().

luciano
  • 13,158
  • 36
  • 90
  • 130

3 Answers3

3

This fulfils @luciano's request to retain functionality of scale_x_date

library('scales')
library(ggplot2)
df <- data.frame(value = rnorm(62), my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))
ggplot(df, aes(x=as.Date(my.date), y=value, group=format(as.Date(my.date),"%W-%b"))) + geom_boxplot() + scale_x_date(date_breaks = "1 week", date_labels="%Y-%b-%d")

Boxplot using scale_x_date

Alternatively, if you don't want the data grouped by week# - which gives you the split around most new years - you can group by week ending Sundays as below. Adjusting from the Sunday weekending, to say Friday, can be achieved with some such code ceiling_date(x, "week") + ifelse(weekdays(x) %in% c("Saturday", "Sunday"), 5, -2)

ggplot(df, aes(x=as.Date(my.date), y=value, group=ceiling_date(my.date, "week"))) + geom_boxplot() + scale_x_date(date_breaks = "1 week", date_labels="%Y-%b-%d")

Group by weekending Sundays

Hedgehog
  • 5,487
  • 4
  • 36
  • 43
2

One option is to transform your date before using ggplot

library(ggplot2)
df <- data.frame(value = rnorm(62), 
my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))
weeks <- format(df$my.date, "%Y/%W")
weeks <- factor(weeks, levels = unique(weeks))

ggplot(df, aes(weeks, value)) +
    geom_boxplot()
dickoa
  • 18,217
  • 3
  • 36
  • 50
  • Is there not a way to do this within `scale_x_date`? – luciano Jan 24 '14 at 10:36
  • Minor point: I'd probably let the formatting take both the year and week number to handle multi-year scenarios and assign it into the data.frame as a new column `df$weeks <- format(df$my.date, "%Y/%W")` – Matt Weller Jan 24 '14 at 10:36
  • Thanks all for responses. However, all the responses so far remove the functionality of `scale_x_date` such as `minor_breaks`. Does anyone have a solution that doesn't have to resort to using `reorder`, `scale_x_discrete` or `factor`? – luciano Jan 24 '14 at 21:16
2
library(ggplot2)    
ggplot(df, aes(format(as.Date(my.date), "%W\n%b"), value)) + geom_boxplot()  

Edit:

To order the dates:

ggplot(df, aes(reorder(format(as.Date(my.date), "%W\n%b"), 
                       as.Date(my.date)), 
               value)) + 
  geom_boxplot() 
lukeA
  • 53,097
  • 5
  • 97
  • 100
  • This can be fixed by `df$week <- factor(format(as.Date(df$my.date), "%W\n%b"))` and `ggplot(df, aes(week, value)) + geom_boxplot() + scale_x_discrete(limits=unique(df$week))` – tonytonov Jan 24 '14 at 11:04
  • You should be able to change the order easily using e.g. `reorder()`: `ggplot(df, aes(reorder(format(as.Date(my.date), "%W\n%b"), as.Date(my.date)), value)) + geom_boxplot()` – lukeA Jan 24 '14 at 11:37