I have a dataset with two variables (Tb and Ta) over time (Date). Looks like this:
` Date Tb Ta Light
1 2015-02-15 01:13:00 36.103 22.751 nightime
2 2015-02-15 01:55:00 36.103 22.626 nightime
3 2015-02-15 02:37:00 35.605 22.626 nightime
4 2015-02-15 03:19:00 35.605 22.751 nightime
5 2015-02-15 04:01:00 36.103 23.001 nightime
6 2015-02-15 04:43:00 35.605 22.876 nightime`
I am trying to make a plot with different shading for levels in the factor 'Light'. So all points with 'nightime' in 'Light' would be shaded in grey while the 'daytime' would be white. Something like this:
Is there a way to get geom_rect()
to work with a factor level? I need all points coded as 'nightime' shaded with a grey background ...
I tried the following based on Using ggplot2 in R, how do I make the background of a graph different colours in different regions?
ggplot() + geom_rect(data=tbdf, (aes(xmin=Date,
xmax=Date, ymin=min(Tb), ymax=max(Tb), fill=Light))) +
geom_line(data = tbdf, aes(x = Date, y = Tb)) +
geom_line(data = tbdf, aes(x = Date, y = Ta), colour='grey') +
xlab('Date') +
ylab('Temperature (°C)')
and it ends up with a legend for Light but still the usual grey shading:
Any suggestions?
Due to a lack of sample data I created some.
library(ggplot2)
library(dplyr)
daytime <- rep(rep(c("day", "night"), each = 12),10)
df <- data.frame(date = 1:length(daytime), daytime, value = rnorm(length(daytime)))
> head(df)
date daytime value
1 1 day -0.7016900
2 2 day -0.5886091
3 3 day -0.1962264
4 4 day 1.3621115
5 5 day -1.5810459
6 6 day -0.6598885
Then I determined the start and end of each day and each night. For the sample data this would not be necessary but I guess the real data are not that simple.
period <- case_when(daytime != lead(daytime) & daytime == "day" ~ "endDay",
daytime != lead(daytime) & daytime == "night" ~ "endNight",
daytime != lag(daytime) & daytime == "day" ~ "beginDay",
daytime != lag(daytime) & daytime == "night" ~ "beginNight")
period[1] <- "beginDay"
period[length(period)] <- "endNight"
Combining both:
rect <- cbind(df,period)
names(rect)[1] <- "date"
and creating 2 dataframes, one for night and one for daytime with the corresponding x values of each period.
rect_night <- na.omit(rect[rect$daytime == "night", ])[ ,-2:-3]
rect_night <- data.frame(start = rect_night[rect_night$period == "beginNight", 1],
end = rect_night[rect_night$period == "endNight", 1])
rect_day <- na.omit(rect[rect$daytime == "day", ])
rect_day <- data.frame(start = rect_day[rect_day$period == "beginDay", 1],
end = rect_day[rect_day$period == "endDay", 1])
Putting alltogether in a plot.
ggplot(alpha = 0.3) +
geom_rect(data = rect_night,aes(xmin = start, xmax = end, ymin = -5, ymax = 5), fill = "grey") +
geom_rect(data = rect_day,aes(xmin = start, xmax = end, ymin = -5, ymax = 5), fill = "yellow") +
geom_line(data = df, aes(x = date, y = value))
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