I saw here that abline() does not work with xts plots. I typically use plot(as.zoo()) of xts objects and ran into the following problem. Let's first generate some dummy time series data (the definition of start and end turn out to be crucial):
library(xts)
start <- strptime("1888-01-01 00:30", format = "%Y-%m-%d %H:%M", tz = "UTC")
end <- strptime("2019-12-31 00:10", format = "%Y-%m-%d %H:%M", tz = "UTC")
n <- 1000
dates <- seq(start, end, length.out = n)
set.seed(1)
dat <- rnorm(n)
ts <- xts(dat, order.by = dates)
Now let's try to plot ts as a zoo object and add lines:
plot(as.zoo(ts), type = "p")
abline(v = as.Date("1950-01-01"), col = "red") # not placed at the right location
abline(v = as.Date("2000-01-01"), col = "blue") # same (wrong) placement
abline(v = strptime("1950-01-01 00:00", format = "%Y-%m-%d %H:%M", tz = "UTC"), col = "green") # also fails
All abline() calls seem to plot in the same (wrong) location, why?
Remark: The following uses a different definition of start and end and that works as expected:
start. <- as.Date(start)
end. <- as.Date(end)
dates. <- seq(start., end., length.out = n)
ts. <- xts(dat, order.by = dates.)
plot(as.zoo(ts.), type = "p")
abline(v = as.Date("1950-01-01"), col = "red")
There are several problems here:
abline doesn't know what class you originally used on the X axis when the plot was created. It just takes the internal numeric value of whatever you give it. If you plot it using one class and use a different class in abline it is not going to work.
In plotting and most other cases it is better to use POSIXct class rather than POSIXlt class. That is do NOT use strptime as it produces POSIXlt. Use as.POSIXct as it produces POSIXct. The internal form of a POSIXlt object is a list of 9 components which abline can't interpret in the desired way.
Regarding the subject of the post this has nothing to do with zoo. abline works this way even without any packages. If you had used plot(dat ~ dates) then the abline command would have resulted in the same output.
Thus the code should be
library(xts)
fmt <- "%Y-%m-%d %H:%M"
start <- as.POSIXct("1888-01-01 00:30", format = fmt, tz = "UTC")
end <- as.POSIXct("2019-12-31 00:10", format = fmt, tz = "UTC")
n <- 1000
dates <- seq(start, end, length.out = n)
set.seed(1)
dat <- rnorm(n)
ts <- xts(dat, order.by = dates)
plot(as.zoo(ts), type = "p")
v <- as.POSIXct("1950-01-01 00:00", format = fmt, tz = "UTC")
abline(v = v, col = "green")