Here's an alternative approach. Instead of dividing the time series into many polygons I decided to draw everything at once (well, twice actually) and limit the plotting region instead.
Generating data and initial plotting:
# random data
set.seed(1)
ts.NAO <- list(NAO_index=rnorm(123, sd=2))
running_mean <- stats::filter(ts.NAO$NAO_index, rep(1, 7)/7)
plot(ts.NAO$NAO_index, type='n', ann=F, xaxt='n', yaxt='n', xlim=c(0, 123))
title(xlab="Years", ylab="NAO SLP Index")
axis(side=1, at=seq(1,123,10), labels=seq(1900,2020,10), las=1) # customizing the x axis
axis(side=2, at=seq(-6,6,0.5), labels=seq(-6,6,0.5)) # customizing the y axis
# save for later use
par0 <- par(c('usr', 'mar'))
# vertical value of dividing point between red and blue
split.at <- 0
# normalized device coordinates of plotting region x and y limits and
# the split point
coords <- list(x=grconvertX(par0$usr[1:2], to='ndc'),
y=grconvertY(c(par0$usr[3:4], split.at), to='ndc'))
Here's a function that creates the lower or upper subfigure and draws the polygon. I didn't want to repeat some parts of code twice, hence the function (although it would be shorter without it).
sub_fig <- function(upper=T, color='red') {
if (upper) {
y.fig <- coords$y[3:2] # subfigure bottom and top
y.usr <- c(split.at, par0$usr[4]) # plot y limits
} else {
y.fig <- coords$y[c(1, 3)]
y.usr <- c(par0$usr[3], split.at)
}
par(fig=c(coords$x, y.fig), mar=rep(0, 4), new=T)
frame()
plot.window(par0$usr[1:2], y.usr, xaxs='i', yaxs='i')
polygon(c(1, seq_along(ts.NAO$NAO_index), length(ts.NAO$NAO_index)),
c(split.at, ts.NAO$NAO_index, split.at),
col=color)
}
# upper
sub_fig()
# lower
sub_fig(F, 'blue')
# restore initial plot coordinates
par(fig=c(0, 1, 0, 1), mar=par0$mar, new=T)
frame()
plot.window(par0$usr[1:2], par0$usr[3:4], xaxs='i', yaxs='i')
abline(h=0, col="blue")
lines(running_mean, col=gray(.7), lty=2, lwd=2)
