Closed vspinu closed 2 years ago
I think the problem is that points()
can't currently add observations to the plot if they're at timestamps that aren't in the initial object.
Can you describe what you're trying to accomplish? Maybe I can help with a work-around.
I want to plot multiple points per timestamp. More technically, I have a data frame of measurements. One columns is a list of numeric vectors. I want to plot those measurements from each vector as points. Each of the points within a vector appears on the same vertical line.
[Edit]: My current workaround is to call points()
multiple times, first with all 1st observations from the vectors, then 2nd etc. Those vectors can be of different length.
This seems to work with quantmod::chart_Series()
, which is what plot.xts()
is based on. Can you confirm this is the behavior you expect? If so, this is a bug.
time0 <- as.POSIXct("2021-11-30 11:24:44.003")
tx <- xts(data.frame("c"=1:5,"c1"=2:6), time0 + c(1,1,1,2,2))
quantmod::chart_Series(tx[c(1, 4), "c"])
quantmod::add_TA(tx[, "c1"], col = "red", pch = 19, type = "p", on = 1)
Related to #216.
Yes, this is precisely what I want. Thanks for looking into it!
These commits fix most cases, but they break one case in issue 216:
# Create some data
# 3 monthly data
x1 <- seq(from = as.Date('2000-01-01'), to = as.Date('2010-12-31'), by = 90)
n <- length(x1)
y1 <- (c(1:n) - n / 2)^3
xts1 <- xts(y1, order.by = x1)
# 2 monthly data
x2 <- seq(from = as.Date('2000-01-01'), to = as.Date('2010-12-31'), by = 60)
y2 <- (c(1:length(x2)) - n / 2)^3
xts2 <- xts(y2, order.by = x2)
plot(xts1) # works
points(xts2, col = "red") # works
points(xts1) # Error in xy.coords(x, y) : 'x' and 'y' lengths differ
I've spent several hours on this so far, but I still don't feel like I'm close to a complete solution. This is hard because plot.xts()
has the observation.based = TRUE
feature that chart_Series()
doesn't. That feature gives you an equally spaced x-axis regardless of the time between each observation. That requires keeping the $Env$xycoords
updated for every series on the plotting device. That functionality doesn't exist right now...
Okay, several more hours of work, and this seems to be working. Now one timestamp can have multiple values, whether observation.based
is TRUE
or FALSE
.
You're also able to add a series that has index values:
Some examples I used for testing/validation:
odd <- c(1, 30, 500, 570, 610)
even <- odd + 15
even[1] <- 3
x <- xts( 1:5, Sys.Date() + odd)
y <- xts(6:10, Sys.Date() + even)
plot(x, observation.based = FALSE)
points(y)
# continued from the chunk above
plot(x, observation.based = TRUE)
points(y)
# your example with observation.based = TRUE
time0 <- as.POSIXct("2021-11-30 11:24:44.003")
tx <- xts(data.frame("c"=1:5,"c1"=2:6), time0 + c(1,1,1,2,2))
plot(tx[c(1, 4), "c"], observation.based = TRUE)
points(tx[, "c1"], col = "red", pch = 19)
# your example where the last observation of the new series is
# after the last value of the original series, and
# observation.based = TRUE
time0 <- as.POSIXct("2021-11-30 11:24:44.003")
tx <- xts(data.frame("c"=1:5,"c1"=2:6), time0 + c(1,1,1,2,3))
plot(tx[c(1, 4), "c"], observation.based = TRUE)
points(tx[, "c1"], col = "red", pch = 19)
Bah, and I just noticed that the x-axis labels are wrong for a couple of those. Back to work...
Okay, the x-axis labels should be fixed in commit 'Optionally return POSIXct values from get_xcoords()'. @vspinu, please test and let me know if you find any issues.
@joshuaulrich sorry for coming late on this. I have just checked and it works as expected and it's very fast. Thanks a bunch for a quick fix!
This branch needs another update.
The current behavior does not extend the x-axis if you add a new series, so this current state of this branch may break existing code.
We should still add this functionality, but it should be optional. We also need to make sure any changes to this branch keep the current behavior to address this issue and #216.
Repeated index does not add points:
Then I thought it picks only first occurence, so let me jitter the index a bit, but it turned out that it would not print anything if the the new index is not exactly the same as the original index: