KOF-ch / tstools

A time series toolbox for official statistics
11 stars 4 forks source link

plot with 2 y-axis: new features proposed #279

Open sboriss opened 5 years ago

sboriss commented 5 years ago

title: "Plot with 2 y-axis" output: html_notebook

The current output of tstools of two time series with 2 y-axis:

library(tstools)
data(KOF)

tsl = KOF$kofbarometer
tsr = KOF$reference
tsplot( tsl, tsr = tsr, auto_legend=F )

In the base R code the plot looks like that (the original code was taken from https://thepracticalr.wordpress.com/2016/08/30/2-y-axis-plotting/):

# final plot
par(mar = c(5, 5, 3, 5))
plot(tsl, type ="l", ylab = "tsl",
     main = "Plot with 2-y axis", xlab = "Time",
     col = "#a9af66", lwd = 2)
par(new = TRUE)
plot(tsr, type = "l", xaxt = "n", yaxt = "n",
     ylab = "", xlab = "", col = "#72791c", lty = 1, lwd = 3)
axis(side = 4)
mtext("tsr", side = 4, line = 3)
legend("bottomright", c("tsl", "tsr"),
       col = c("#a9af66", "#72791c"), lty =1, lwd = c(2,3))

IMHO, this way of visualiasation better represents the comovement between the time series. It would be nice to have this option in the tstools package.

The base R plot adjusts the two time series to have a) the same range. Additionally, one could impose that both time series have b) the same mean c) the same mean and range. The following code implements transformations:

tsl_min = min( tsl )
tsl_max = max( tsl )
tsl_mean = mean( tsl )
tsl_rng = tsl_max - tsl_min

tsr_min = min( tsr )
tsr_max = max( tsr )

### set the same mean
tsr_new_mean = tsr - mean( tsr )  + mean( tsl )

### set the same range (and the same min/max values)
tsr_new_range = ( tsr - tsr_min ) / max( tsr - tsr_min ) * tsl_rng + tsl_min

cat( "range( tsr_new_range ) = ", max(tsr_new_range) - min(tsr_new_range) )
cat( "range( tsl           ) = ", tsl_max - tsl_min )

cat( "mean( tsr_new_range  ) = ", mean( tsr_new_range ) )
cat( "mean( tsl            ) = ", mean( tsl    ) )

### set the same mean and range
tsr_new_range_mean = tsr_new_range - mean( tsr_new_range ) + mean( tsl )

cat( "mean( tsr_new_range_mean ) = ", mean( tsr_new_range_mean ) )
cat( "mean( tsl    ) = ", mean( tsl    ) )

cat( "range( tsr_new_range_mean ) = ", max(tsr_new_range_mean) - min(tsr_new_range_mean) )

In tstools, the transformed time series look like that:

tsplot( tsl, tsr_new_mean , auto_legend=F,
               manual_value_ticks_l = seq(60,120,by=10))
tsplot( tsl, tsr_new_range, auto_legend=F,
               manual_value_ticks_l = seq(60,120,by=10))
tsplot( tsl, tsr_new_range_mean, auto_legend=F,
               manual_value_ticks_l = seq(60,120,by=10))

But the information on the original scale of the RHS variable is lost!

Unfortunate scaling

The alignment of the two time series sometimes can be rather unfortunate:

### unfortunate scaling
tsplot( tsl, tsr = ( tsr - tsr_min ) / max( tsr - tsr_min ) * tsl_rng, auto_legend=F )

but never with options suggested above.