joshuaulrich / xts

Extensible time series class that provides uniform handling of many R time series classes by extending zoo.
http://joshuaulrich.github.io/xts/
GNU General Public License v2.0
220 stars 71 forks source link

on=0 does not appear to work #348

Closed crossxwill closed 1 year ago

crossxwill commented 3 years ago

Description

I want to generate two legends on a single plot object. However, using addLegend(..., on=0) renders a new plot object each time addLegend is called.

Expected behavior

Single plot object with two legends.

Minimal, reproducible example

library(xts)

data(USAccDeaths)

USAccDeaths <- as.xts(USAccDeaths)

plot.xts(USAccDeaths)

addLegend("topleft", legend.names=c("Deaths"), col=c("black"), lty=1:2, cex=0.8, on=0)
addLegend("topright", legend.names=c("AccDeaths"), col=c("black"), lty=1:2, cex=0.8, on=0)

## sample code creates 3 separate plot objects

Session Info

R version 3.6.3 (2020-02-29)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] xts_0.12.1 zoo_1.8-8 

loaded via a namespace (and not attached):
[1] compiler_3.6.3  tools_3.6.3     grid_3.6.3      lattice_0.20-38

Work-around

Embed the addLegend commands as a vector of characters in the panels argument.

library(xts)

data(USAccDeaths)

USAccDeaths <- as.xts(USAccDeaths)

plot.xts(USAccDeaths, panels=
  c('addLegend("topleft", legend.names=c("Deaths"), col=c("black"), lty=1:2, cex=0.8)',
    'addLegend("topright", legend.names=c("AccDeaths"), col=c("black"), lty=1:2, cex=0.8)')
  )
joshuaulrich commented 1 year ago

I just noticed I never answered you. I'm sorry. Your solution is one way to do it. Another is to (re-)assign the plot object to a variable as you add elements, and only print() the plot when you've added everything.

data(USAccDeaths)
USAccDeaths <- as.xts(USAccDeaths)

p <- plot.xts(USAccDeaths)
p <- addLegend("topleft", legend.names=c("Deaths"), col=c("black"), lty=1:2, cex=0.8, on=0)
p <- addLegend("topright", legend.names=c("AccDeaths"), col=c("black"), lty=1:2, cex=0.8, on=0)
print(p)

Your original code renders the plot 3 times because you call 3 plotting functions without assigning the result. R automatically calls print() on an expression when it's evaluated and not assigned to anything.

I'm going to close this because plot.xts() is behaving as expected. But feel free to ask follow-up questions.