4

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?

zx8754
  • 52,746
  • 12
  • 114
  • 209
Daniele L
  • 77
  • 1
  • 6
  • I mean, `aes(NULL, NULL)` isn't in the example you're following and seems weird. I would get rid of that. – Gregor Thomas Jul 22 '16 at 21:50
  • I tried without that, and removing the -0.5 and +0.5 for the x max and min it still makes it all one colour (the nightime one). I've edited the post to remove it. – Daniele L Jul 22 '16 at 21:57
  • It would also help if you would share your data with `dput()`, `dput(head(tbdf, 20))`, copy/pasting to read in your POSIX datetime is a real pain. Also make sure you show enough data so that it's not all nighttime. The real solution will probably be to create a summary data frame that has the transition points from night to day to plot 2 rectangles per day rather than 1 rectangle for every row of data. – Gregor Thomas Jul 22 '16 at 22:01
  • It did seem to be a problem with the format for Date. I've gone back to the original excel file and changed it from the 2015-02-15 01:13:00 format to a number (42050.05). Now I just have to clean up the theme a bit. Thank you for your help. – Daniele L Jul 22 '16 at 22:25

2 Answers2

2

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))

enter image description here

Alex
  • 4,925
  • 2
  • 32
  • 48
2

It seems to have been a problem with the Date format. Changing it from 2015-02-15 01:13:00 format to a number (eg. 42050.05) worked great. Here's the code I used

ggplot() + geom_rect(data=tbdf, (aes(xmin=Date-0.5, xmax=Date+0.5, 
ymin=min(Ta)-0.5, ymax=max(Tb)+0.5, fill=factor(Light)))) +
scale_fill_manual(values=c("grey", "white"), guide=FALSE) +
geom_line(data = tbdf, aes(x = Date, y = Tb), size=0.8) +
geom_line(data = tbdf, aes(x = Date, y = Ta), colour='grey50', size=0.8)  +
ylab('Temperature (°C)')

Which gave me this enter image description here

Which cleans up nicely.

Daniele L
  • 77
  • 1
  • 6