Tick labels with exponents

[28th March, 2022] FYI: I wrote this a really long time again. I am posting it mostly so I can find it when I need it. You are welcome to provide me with more efficient ways to do this and I would be happy to incorporate them.

One thing I find myself doing all the time is plotting data on a logarithmic scale. Sometimes I have a logarithmic x-axis, a logarithmic y-axis or both. Many people often find logarithmic axes confusing, and so it is helpful if the tick labels are on the original scale. My code here will demonstrate how to do this for base ten logarithms, but it is easy to adapt for any other base.

First we need some exponential data for our example

x =  10^runif(100, 0, 5)
y = 3 * x + 2 + rexp(100)

log.x = log10(x)
log.y = log10(y)

Now we plot the data without the axes but put nice labels on the axes

plot(log.x, log.y,
     axes = FALSE,
     xlab = expression(log[10](x)),
     ylab = expression(log[10](y)))

Now get the list of exponents we need for the x-axis tick marks

x.exponents = pretty(range(log.x))
y.exponents = pretty(range(log.y))

I find it helps to take a slightly smaller number of exponents than {\tt pretty} returns

x.exponents = x.exponents[-c(1,length(x.exponents))]
y.exponents = y.exponents[-c(1,length(y.exponents))]

Next we draw the x and y axes without the ticks or labels,

axis(1, at = x.exponents, tick = FALSE, labels = FALSE)
axis(2, at = y.exponents, tick = FALSE, labels = FALSE)

and then we add the x-axis tick marks. This this is done a tick at a time.

for(i in 1:length(x.exponents)){
  if(x.exponents[i] ==0 )
    axis(1, at = x.exponents[i], labels = "1")
  else if(x.exponents[i] == 1)
    axis(1, at = x.exponents[i], labels = "10")
  else
    axis(1, at = x.exponents[i], 
         labels = eval(substitute(
                         expression(10^x),
                         list(x = x.exponents[i]))))
}

And we do the same for the the y-axis tick marks.

for(i in 1:length(y.exponents)){
  if(y.exponents[i] == 0)
    axis(2, at=y.exponents[i], labels="1")
  else if(y.exponents[i] == 1)
    axis(2, at=y.exponents[i], labels="10")
  else
    axis(2, at = y.exponents[i], 
         labels = eval(substitute(
                     expression(10^y),
                     list(y = y.exponents[i]))))
}

And finally draw we a box around the whole thing.

box()

Et voilà

Share Button

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.