1

I am using native R plot function to genertae graphics. looking to add a double x-axis on same plot. One holds doubles and the other x-axis holds Date object. I am using the following commands but they dont seem to work.

First x-axis:

axis.Date(1,at=seq(min(x$Date),na.rm=TRUE,max(x$Date),na.rm=TRUE,by="2 years"),format ="%Y-%m-%d",col.axis="white", cex=1)

Second x-axis:

axis(1,at=seq(min(f), max(f), by = 0.1), col.axis="white", cex=1)

The parameters for the R native plot:

x11()                                                                                    
 par(mfrow=c(1,1),oma = c(0, 0, 2, 0) ) 

Result is only Dates on x-axis.

Guoran Yun
  • 319
  • 2
  • 14
Ain Soph
  • 11
  • 1
  • 2

1 Answers1

1

Up front: dual axes can easily be mis-used by mis-representing the data and/or ranges. It's easy for eyes to misconstrue correlation or relationships based on imperfect axis decisions. For scatter plots (such as below), I'm not a fan and tend to avoid them ... but I do use them under very controlled circumstances, as they can provide visual correlation of relative trends.

When I must do it, I'm a fan of using color as a way to more strongly tie points (or lines) with particular axes, though of course this does not work as well with color-impaired readers.

Given that preface ...

I believe the easiest way to handle multiple axes in base-R is to use par(new=TRUE) between plots. Here's an example:

par(mar = c(4,4,4,4) + 0.1)

plot(disp ~ mpg, data = mtcars, las = 1)

par(new = TRUE)

dat <- data.frame(dat = Sys.Date() + 0:5, y = 1:6)
plot(y ~ dat, data = dat, ann = FALSE, yaxt = "n", xaxt = "n", pch = 16, col = "red")
axis.Date(3, dat$dat[1], col = "red", line = 1)
axis(4, col = "red", line = 1, las = 1)

base R graphic with dual axes

Other differentiating techniques include shapes or line-types (if lines) specific to each side, and adding those as clear markers on the secondary axes.

The use of par(new=TRUE) simply allows the next plot command to not reset/clear the canvas before starting over. This means that the subsequent plotting functions have no knowledge of what is existing. From ?par:

     'new' logical, defaulting to 'FALSE'.  If set to 'TRUE', the next
          high-level plotting command (actually 'plot.new') should _not
          clean_ the frame before drawing _as if it were on a *_new_*
          device_.  It is an error (ignored with a warning) to try to
          use 'new = TRUE' on a device that does not currently contain
          a high-level plot.

It doesn't work well with all plotting mechanisms (certainly nothing grid or ggplot2), and anything that might be sensitive to margins or oma or other parameters should be tested carefully with various ranges of data.

I intentionally used line=1 to "bump out" the top/right axes, another way to set them apart. Frankly, I often do that for the bottom/left (primary) axes as well, it can be aesthetically preferred ... but it's an option and not required for this technique to at least start the process.

r2evans
  • 141,215
  • 6
  • 77
  • 149