I'm trying to plot time series data by week and month; ideally, I think, I'd like to use boxplots to visualise daily data binned by week. While I can change the labels and gridlines on the x-axis using scale_x_date
, that won't affect the points in the plot.
Here's a demonstration of the problem and my current (clumsy) solution.
library(zoo)
library(ggplot2)
d = as.Date(c(as.Date("2007-06-01"):as.Date("2008-05-31"))) # using zoo to reformat numeric
x = runif(366, min = 0, max = 100)
df = data.frame(d,x)
# PROBLEM #
p = ggplot(df, aes(d, x))
p + geom_point()
p + geom_boxplot() # more or less useless
# CURRENT FIX #
df$Year.Month <- format(df$d, "%Y-%m")
p = ggplot(df, aes(Year.Month, x))
p + geom_point(alpha = 0.75)
p + geom_boxplot() # where I'm trying to get to...
I feel certain that there's a more elegant way to do this from within ggplot
. Am I right?
@shadow's answer below is much neater. But is there a way to do this using binning? Using stats
in some form, perhaps?
year.month.r <- seq.Date(as.Date("2016-10-01"), as.Date("2018-02-01"), by = "month") df.r <- data.frame(year.month.r, total.a) With this, you have your monthly (by = "month") time series defined and you can get it plotted with ggplot
%Y: Year with century. The ggfortify package is an extension to ggplot2 that makes it easy to plot time series objects (Horikoshi and Tang 2017). It can handle the output of many time series packages, including: zoo::zooreg (), xts::xts (), timeSeries::timSeries (), tseries::irts (), forecast::forecast (), vars:vars ().
We can use the qplot () function in the ggplot2 package to quickly plot a variable such as air temperature ( airt) across all three years of our daily average time series data. # plot air temp qplot (x=date, y=airt, data =harMetDaily. 09. 11, na.rm=TRUE, main = "Air temperature Harvard Forest 2009-2011" , xlab = "Date", ylab= "Temperature (°C)" )
The ggplot2 package recognizes the date format and automatically uses a specific type of X axis. If the time variable isn’t at the date format, this won’t work. Always check with str (data) how variables are understood by R. If not read as a date, use lubridate to convert it. Read more about this here.
You can treat Dates as dates in R, and use scale_x_date() in ggplot to get the x-labels you want.
Also, I find it easier to just create a new variable-factor called "Month" to group the boxplots by month. In this case I used lubridate to accomplish the task.
If you do not want to go through the trouble of creating a new variable "Month", your bloxplot will be plotted on the 15th of the month, making the viz reading a bit more difficult.
library(magrittr)
library(lubridate)
library(dplyr)
df %>%
mutate(Date2 = as.Date(paste0("2000-", month(d), "-", "01"))) %>%
mutate(Month = lubridate::month(d)) %>%
ggplot(aes(Date2, x, group=Month)) +
geom_boxplot() +
scale_x_date(date_breaks="1 month", date_labels = "%b")
If you do not create the variable "Month", boxplots won't align nicely with the x tick marks:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With