Reputation: 522
I was building a custom function that automatically add legends to a plot.xts object.
Code here:
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
plot_object <- xts:::current.xts_chob()
columns <- plot_object$Env$xdata
columnnames <- plot_object$Env$column_names
if(!is.null(event.lines)) {
# error occurred
addEventLines(xts(event.labels, as.Date(event.lines)),
offset = event.offset, pos = event.pos,
srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
I failed to plot multiple windows with no messages when I set multi.panel = TRUE
. But if I remove codes below plot.xts
or move them to above plot.xts
, it works again.
Remove codes below plot.xts
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
Move codes to be above plot.xts
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
columns <- ncol(R)
columnnames <- colnames(R)
if(!is.null(event.lines)) {
# error occurred
addEventLines(xts(event.labels, as.Date(event.lines)),
offset = event.offset, pos = event.pos,
srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
Any suggestions?
Upvotes: 0
Views: 172
Reputation: 176718
You need to keep track of the plot object you're building, and return it so it auto-prints. You should also not access unexported objects (xts:::current.xts_chob()
) because there's no guarantee they will remain consistent across versions.
chartS <-
function(R, y = NULL, multi.panel = FALSE, type = "l", yaxis.same = TRUE,
event.lines = NULL, event.labels = NULL, event.col = 1,
event.offset = 1.2, event.pos = 2, event.srt = 90, event.cex = 1.5,
lty = 1, lwd = 2, legend.loc = NULL, legend.names = NULL, ...)
{
plot_object <- plot.xts(R, y = y, multi.panel = multi.panel, type = type,
yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
columns <- plot_object$Env$xdata
columnnames <- plot_object$Env$column_names
if(!is.null(event.lines)) {
plot_object <-
addEventLines(xts(event.labels, as.Date(event.lines)), offset = event.offset,
pos = event.pos, srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
plot_object <- addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
return(plot_object)
}
Upvotes: 2