Reputation: 35
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)?
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
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')
Data:
n <- 1e2
set.seed(42)
dat <- data.frame(data=runif(n), days=sort(sample(seq.int(0, 10, .01), n)))
Upvotes: 1