# [R] pretty for a log-axis

Martin Maechler maechler at stat.math.ethz.ch
Thu Apr 15 14:44:23 CEST 2004

```>>>>> "BXC" == BXC (Bendix Carstensen) <bxc at steno.dk>
>>>>>     on Thu, 15 Apr 2004 09:54:49 +0200 writes:

BXC> Is there a function that does the same as pretty but on
BXC> a log-scale?  Suppose you have

BXC> x <- exp( runif( 100, 0, 6 ) )

BXC> (which will between 1 and 403), then I would like to
BXC> have a result like:

BXC> log.pretty( x )
BXC>  1 5 10 50 100 500

axTicks()  can be used for this and will use the same algorithm
that R uses internally;  it's not as flexible as pretty() is,
but should fulfill your needs.

As I (author of the function) just see, the documentation of
axTicks is insufficient:
?axTicks points to ?par ("xaxp") which points
back to ?axTicks without explaining the crucial meaning of  axp
for the log case:

axp	 values
------	 ---------------
1	   1      * 10^j
2       (1,5)   * 10^j
3       (1,2,5) * 10^j

Also, contrary to help(axTicks), the result of axTicks() does
not depend on the graphics state at all --- *when* all arguments
are specified (differently from the default NULL).

Here is an example "script":

## just to "repeat your example" :
> set.seed(1); x <- exp(runif(100,0,6)); rx <- range(x); summary(x)
Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
1.084   6.950  18.680  62.230  99.800 384.300

> axTicks(1, axp=c(rx, 1), usr=c(1,3), log=TRUE)
   10  100 1000
> axTicks(1, axp=c(rx, 2), usr=c(1,3), log=TRUE)
   10   50  100  500 1000
> axTicks(1, axp=c(rx, 3), usr=c(1,3), log=TRUE)
   10   20   50  100  200  500 1000
> axTicks(1, axp=c(rx, 3), usr=c(0,3), log=TRUE)
    1    2    5   10   20   50  100  200  500 1000

--- note that "usr" is in the log-transformed scale.

Probably the whole thing is most easily understood by looking at
the source (*including* the comments you usually won't see!)
of which the relevant part is

........
if(log && axp > 0) { ## special log-scale axp[]
if(!any((iC <- as.integer(axp)) == 1:3))
stop("invalid positive axp")
if(is.null(usr)) usr <- par("usr")[if(is.x) 1:2 else 3:4]
else if(!is.numeric(usr) || length(usr) != 2) stop("invalid `usr'")
ii <- round(log10(axp[1:2]))
x10 <- 10^((ii - (iC >= 2)):ii)
r <- switch(iC,				## axp
x10,			## 1
c(outer(c(1,  5), x10))[-1],## 2
c(outer(c(1,2,5), x10))[-1])## 3
r[usr <= log10(r) & log10(r) <= usr]
} else { # linear
........

Hoping that helps,
Martin Maechler

```