Reputation: 1517
I haven't found any history questions about this... I want to highlight the weekend performance for a ggplot graph, so that user could tell directly one the graph which part(may be a gray shade?) is weekend performance right away.
Here's a simple version of testing data:
test <- data.frame(DATE=seq(from = as.POSIXct("2014-07-16 01:00"), to = as.POSIXct("2014-07-30 00:00"), by = "hour"),count=floor(runif(336,1,100)))
Simple version of my graph is:
ggplot() + geom_line(aes(x=DATE,y=count),data=test) + labs(title="test")
So that result could be like something below...
Upvotes: 9
Views: 4396
Reputation: 21948
Here is an approach using Tydiverse tools, and more precisely geom_tile
. The advantage is that you have not to precise the x
boundaries.
library(dplyr)
library(lubridate)
library(ggplot2)
test %>%
# My preference :-)
rename_all(tolower) %>%
# Computing the weekends by converting in weekday starting on monday to ease the cut
mutate(weekend = wday(date, week_start = getOption("lubridate.week.start", 1)) > 5) %>%
ggplot() +
geom_line(aes(x = date, y = count)) +
# And here is the trick!
scale_fill_manual(values = c("alpha", "yellow")) +
geom_tile(aes(
x = date,
y = min(count),
height = Inf,
fill = weekend
), alpha = .4)
Note: I've written a more detailed post on this topic.
Upvotes: 5
Reputation: 11
I found a nice solution with geom_bar()
where you make a vector which is infinite on weekends, the remaining values are NA and will not be plotted. I used lubridate
as I am more familiar with it. I also had to name the aesthetics in the first call to ggplot()
so the axes inherit their proper names and y
is not labelled as "weekend":
library(lubridate)
library(ggplot2)
test <- data.frame(DATE=seq(from = as.POSIXct("2014-07-16 01:00"), to = as.POSIXct("2014-07-30 00:00"), by = "hour"),count=floor(runif(336,1,100)))
your_plot <- ggplot(test) + geom_line(aes(x=DATE,y=count)) + labs(title="test")
your_plot
test$wd <- wday(test$DATE, label = TRUE)
test$weekend[test$wd=="Sat" | test$wd=="Sun"] <- 1/0
highlight_plot <- ggplot(test, aes(x= DATE, y = weekend)) +
geom_bar(stat="Identity", aes(y=weekend), col="yellow", alpha=.4, width = 1) +
geom_line(aes(x=DATE,y=count)) + labs(title="test")
highlight_plot
This solution is pretty flexible and it's easy to adapt the method to highlight different vectors of dates.
Upvotes: 1
Reputation: 143
Using geom_area() is more concise, and will work for any date range.
library(ggplot2)
test <- data.frame(DATE=seq(from = as.POSIXct("2014-07-16 01:00"),
to = as.POSIXct("2014-07-30 00:00"),
by = "hour"),
count=floor(runif(336,1,100)))
test$weekend <- weekdays(test$DATE) %in% c("Saturday", "Sunday")
ggplot(data=test, aes(x=DATE, y=count)) +
geom_area(aes(y=weekend*max(count)), fill="yellow") +
geom_line() +
labs(title="test")
Upvotes: 12
Reputation: 9592
Here's code that does both weekends in your data. You could generalize to any number of weekends by adding more geom_rect() calls (or calling a loop that does).
# your data
test <- data.frame(DATE=seq(from = as.POSIXct("2014-07-16 01:00"), to = as.POSIXct("2014-07-30 00:00"), by = "hour"),count=floor(runif(336,1,100)))
your_plot <- ggplot(test) + geom_line(aes(x=DATE,y=count)) + labs(title="test")
# get all the start and end points
library(lubridate) # for hour function
sats <- which(hour(test$DATE)==0 & weekdays(test$DATE)=='Saturday')
suns <- which(hour(test$DATE)==23 & weekdays(test$DATE)=='Sunday')
# do your plot plus weekend highlights
your_plot +
geom_rect(aes(xmin=DATE[sats[1]], xmax=DATE[suns[1]],
ymin=min(count), ymax=max(count)),
fill='yellow', alpha=.005) +
geom_rect(aes(xmin=DATE[sats[2]], xmax=DATE[suns[2]],
ymin=min(count), ymax=max(count)),
fill='yellow', alpha=.005)
Upvotes: 5
Reputation: 899
As per my comment, hopefully this is what you are looking for:
test <- data.frame(DATE=seq(from = as.POSIXct("2014-07-16 01:00"), to = as.POSIXct("2014-07-30 00:00"), by = "hour"),count=floor(runif(336,1,100)))
ggplot() + geom_rect(aes(xmin = as.POSIXct("2014-07-26 00:00"), xmax = as.POSIXct("2014-07-28 00:00"), ymin = 0, ymax = 100), fill = "yellow")+
geom_line(aes(x=DATE,y=count),data=test) + labs(title="test")
Giving pretty much exactly the image in the question. You can alter fill to change the colour and easily add further rectangles at different points if required.
Upvotes: 1