Summary + Thx: [R] How to add a top X-axis with a different logarithmic scale?

Itay Furman itayf at fhcrc.org
Mon Mar 29 20:59:07 CEST 2004


Thanks to Marc Schwartz and Jim Lemon for their solutions, and 
the very useful document by JL.

This is a summary in case it is useful to others.

My problem was to provide, for the same data series, two 
different X ordinates ('axes' was probably a misnomer here).
In this case, both ordinates are logarithmic and differ only by 
scale; the solution should work with more complicated 
transformations.


################################################################
####
####    Solution based on Jim Lemon's "Kickstarting R",
####        section "Plotting more than one data series".
####    http://cran.r-project.org
####        (under "Contributed Documentation").

####    Here, the top axis is produced as a side-effect of
####    a plot of the transformed data series, while hiding the
####    actual points.

x <- c(1.1 * 1:4, 25 * 1:5) / 50e+03
y <- c(0.15 * 1:4, 0.6 + 0.05 * 1:5)

old.par <- par(no.readonly=TRUE)
xlim <- range(x)
ylim <- c(0, 1)

plot(x, y, type="l", log="x", xlim=xlim, ylim=ylim,
     xlab="Fraction", ylab="IC")
par(new=T)
## replot the transformed data series (x -> x*4.1e06). We must
## specify 'log="x"' and 'ylim=ylim' to have the correct range;
## 'axes=F' suppresses plotting the axes at bottom and left; 
## 'lty=0' hides the data points.
plot(x*4.1e06, y, type="l", log="x", ylim=ylim, axes=F, lty=0,
     xlab="", ylab="")
## Now, really plot the top X-axis.
## plot() command.
axis(3)
mtext("Total", side=3, line=2)

par(old.par)
################################################################


################################################################
####    Marc Schwartz's solution works 'as-is', so I merely
####    reproduce it here for completeness.

x <- c(1.1 * 1:4, 25 * 1:5) / 50e+03
y <- c(0.15 * 1:4, 0.6 + 0.05 * 1:5)

old.par <- par(no.readonly=TRUE)
xlim <- range(x)
ylim <- c(0, 1)

plot(x, y, type = "l", log = "x", xlim = xlim, ylim = ylim)

# Set scaling factor
sf <- 4.1e06

# Now set up new upper x axis range based upon sf
xlim.3 <- xlim * sf

# Now create axis tick mark positions for the new scale
# We will use axTicks() and need to consider that when log scales
# are in use, things get a little hairy. So:

# We need to define a new par("xaxp") based upon xlim.3
# We also need to define a new par("usr")[1:2], which is the
# range of the x axis. When log scales are in use, the actual
# range is 10 ^ par("usr")[1:2], so we take these values and rescale
# using 'sf'. We then convert the result back to log scales using
# log10() to get 'usr':
tm <- axTicks(3, axp = c(range(xlim.3), 3),
              usr = log10(10 ^ par("usr")[1:2] * sf),
              log = TRUE)

# Now we can draw axis 3, using the adjusted scaling
# We need to adjust the scaled tick mark positions back
# to the actual range of the x axis, so 'at' is adjusted
# here by the sf, but the labels stay as rescaled:
axis(3, at = tm / sf, labels = tm)

par(old.par)
################################################################


	Itay




More information about the R-help mailing list