update : copied material that was on the R wiki at http://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxes , the link is now broken: also accessible from the return path machine
Two different y axes in the same section
(some material originally Daniel Rydle 2006/03/31 15:26)
Please note that there are very few situations where it is advisable to use two different scales on the same site. It is very easy to mislead the viewer. Check out the following two examples and comments on this issue ( example1 , example2 from Unch Charts ), as well as in this article by Stephen Fuer (which concludes: “I certainly can’t conclude once and for all that double-scaled graphs will never useful, only I can’t come up with a situation that justifies them in the light of other best solutions. ") Also see point 4 in this cartoon ...
If you decide, the main recipe is to create your first graph, set par(new=TRUE) so that R doesn't clear the graphics device, create a second graph with axes=FALSE (and set xlab and ylab to be blank - ann=FALSE should also work), and then use axis(side=4) add a new axis to the right and mtext(...,side=4) to add an axis label to the right. Here is an example that uses some collected data:
set.seed(101) x <- 1:10 y <- rnorm(10) ## second data set on a very different scale z <- runif(10, min=1000, max=10000) par(mar = c(5, 4, 4, 4) + 0.3) # Leave space for z axis plot(x, y) # first plot par(new = TRUE) plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "") axis(side=4, at = pretty(range(z))) mtext("z", side=4, line=3)
twoord.plot() in the plotrix package automates this process, like doubleYScale() in the latticeExtra package.
Another example (adapted from Robert W. Baer’s mailing list R):
## set up some fake test data time <- seq(0,72,12) betagal.abs <- c(0.05,0.18,0.25,0.31,0.32,0.34,0.35) cell.density <- c(0,1000,2000,3000,4000,5000,6000) ## add extra space to right margin of plot within frame par(mar=c(5, 4, 4, 6) + 0.1) ## Plot first set of data and draw its axis plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="", type="b",col="black", main="Mike test data") axis(2, ylim=c(0,1),col="black",las=1) ## las=1 makes horizontal labels mtext("Beta Gal Absorbance",side=2,line=2.5) box() ## Allow a second plot on the same graph par(new=TRUE) ## Plot the second plot and put axis scale on right plot(time, cell.density, pch=15, xlab="", ylab="", ylim=c(0,7000), axes=FALSE, type="b", col="red") ## a little farther out (line=4) to make room for labels mtext("Cell Density",side=4,col="red",line=4) axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1) ## Draw the time axis axis(1,pretty(range(time),10)) mtext("Time (Hours)",side=1,col="black",line=2.5) ## Add Legend legend("topleft",legend=c("Beta Gal","Cell Density"), text.col=c("black","red"),pch=c(16,15),col=c("black","red"))

Similar recipes can be used for overlaying charts of different types - bar charts, histograms, etc.