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