Laura C
Laura C

Reputation: 35

How to add grey shadings to distinguish night from day in a plot?

I have been manually adding shade boxes to my plots to distinguish day and night time using the annotate function, but it is tiresome. I'm wondering if there is a more efficient way of doing this. Perhaps by having an extra column stating whether the data was taken during day time (light) or night time (dark)?

Temperature data across days with dark boxes indicating night

This is example of what the data looks like:

data days lightcycle
37 0.08 dark
37.2 0.1 dark
37.0 0.11 dark
37.3 0.13 dark
37 0.15 light
37 0.16 light
38 0.18 light
38.1 0.20 light
38.2 0.21 light
38.3 0.23 light

Upvotes: 1

Views: 458

Answers (1)

jay.sf
jay.sf

Reputation: 73352

We could create sequences, where the nights start and end to mapply over with rect. I use night time starting at 6pm, ending 6am.

(sq <- cbind(seq(-.25, max(dat$days) , 1), seq(.25, max(dat$days) + 1, 1)))
#        [,1]  [,2]
#  [1,] -0.25  0.25
#  [2,]  0.75  1.25
#  [3,]  1.75  2.25
#  [4,]  2.75  3.25
#  [5,]  3.75  4.25
#  [6,]  4.75  5.25
#  [7,]  5.75  6.25
#  [8,]  6.75  7.25
#  [9,]  7.75  8.25
# [10,]  8.75  9.25
# [11,]  9.75 10.25

To draw the shading first, we use panel.first=.

plot(dat$days, dat$data, type='l', main='My plot', xlab='days', ylab='data',
     panel.first=mapply(\(x, y) with(par(), rect(x, usr[3], y, usr[4], col='grey81', border=NA)),
                        c(-sq[, 1], sq[, 1]),
                        c(-sq[, 2], sq[, 2])))
legend(par()$usr[1], par()$usr[3] - .18, legend=c('data', 'night', 'day'), xpd=TRUE, 
       lty=c(1, 0, 0), pch=c(NA, 22, 22), cex=.8,
       horiz=TRUE, pt.bg=c(NA, 'grey81', 0), col=c(1, 'grey81', 'grey81'), bty='n')

enter image description here


Data:

n <- 1e2
set.seed(42)
dat <- data.frame(data=runif(n), days=sort(sample(seq.int(0, 10, .01), n)))

Upvotes: 1

Related Questions