Displaying minor logarithmic ticks in x-axis in R

血红的双手。 提交于 2019-12-02 20:50:58

There is a function minor.tick in the package Hmisc, but that one deals poorly with logarithmical scales. I use the following function for getting minor ticks that follow the logarithmical scale. ax is the axis you use it on (same as for the function axis), n is the number of minor ticks (default to 9), t.ratio is the ratio between the major and the minor ticks, and with ... you can pass extra parameters to axis

edit : Nice idea in the comments, so I edited my function. There are two extra parameters, mn and mx for the minimum and the maximum on the logarithmic scale (mn=0 thus means the minimum is 10^0 or 1 !)

The function:

minor.ticks.axis <- function(ax,n,t.ratio=0.5,mn,mx,...){

  lims <- par("usr")
  if(ax %in%c(1,3)) lims <- lims[1:2] else lims[3:4]

  major.ticks <- pretty(lims,n=5)
  if(missing(mn)) mn <- min(major.ticks)
  if(missing(mx)) mx <- max(major.ticks)

  major.ticks <- major.ticks[major.ticks >= mn & major.ticks <= mx]

  labels <- sapply(major.ticks,function(i)
            as.expression(bquote(10^ .(i)))
          )
  axis(ax,at=major.ticks,labels=labels,...)

  n <- n+2
  minors <- log10(pretty(10^major.ticks[1:2],n))-major.ticks[1]
  minors <- minors[-c(1,n)]

  minor.ticks = c(outer(minors,major.ticks,`+`))
  minor.ticks <- minor.ticks[minor.ticks > mn & minor.ticks < mx]


  axis(ax,at=minor.ticks,tcl=par("tcl")*t.ratio,labels=FALSE)
}

This can be applied as follows :

x <- 10^(0:8)
y <- 1:9
plot(log10(x),y,xaxt="n",xlab="x",xlim=c(0,9))
minor.ticks.axis(1,9,mn=0,mx=8)

Gives :

Here is a simple function to to this:

log10.axis <- function(side, at, ...) {
    at.minor <- log10(outer(1:9, 10^(min(at):max(at))))
    lab <- sapply(at, function(i) as.expression(bquote(10^ .(i))))
    axis(side=side, at=at.minor, labels=NA, tcl=par("tcl")*0.5, ...)
    axis(side=side, at=at, labels=lab, ...)
}

Here is an example:

x <- exp(rnorm(200, 5))
hist(log(x), 20, xaxt="n", xlim=c(0, 8))
log10.axis(1, at=seq(0, 8, 2))

Gives:

Try magaxis in package magicaxis.

In ggplot2, we can use annotation_logticks together with scales::trans_breaks and scales::trans_format. Below is an example taken from the link above.

    library(ggplot2)

    a <- ggplot(msleep, aes(bodywt, brainwt)) +
      geom_point(na.rm = TRUE) +
      scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x),
        labels = scales::trans_format("log10", scales::math_format(10^.x))
      ) +
      scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x),
        labels = scales::trans_format("log10", scales::math_format(10^.x))
      ) +
      theme_bw()

    a + annotation_logticks() # Default: log ticks on bottom and left

There is the minorAxis function in the StratigrapheR package, that can be used for any kind of minor ticks. It can be used with the seq_log function to make logarithmic ticks:

library(StratigrapheR)

x <- exp(rnorm(200, 5))
hist(log10(x), 20, xaxt="n", xlim=c(0, 4), xlab = "x", main = "Logarithmic Histogram of x")

ticks <- seq_log(10^0,10^4, divide = T)

lab <- sapply(0:4, function(i) as.expression(bquote(10^ .(i))))

minorAxis(1, at.maj = log10(ticks[[1]]), at.min = log10(ticks[[2]]), labels = lab)

Gives:

Use "" for the labels of the minor ticks.

There was a small error,

lims<-lims[3:4] was missing

   minor.ticks.axis <- function(ax,n,t.ratio=0.5,mn,mx,...){

  lims <- par("usr")
  if(ax %in%c(1,3)) lims <- lims[1:2] else lims <- lims[3:4]

  major.ticks <- pretty(lims,n=5)
  if(missing(mn)) mn <- min(major.ticks)
  if(missing(mx)) mx <- max(major.ticks)

  major.ticks <- major.ticks[major.ticks >= mn & major.ticks <= mx]

  labels <- sapply(major.ticks,function(i)
            as.expression(bquote(10^ .(i)))
          )
  axis(ax,at=major.ticks,labels=labels,...)

  n <- n+2
  minors <- log10(pretty(10^major.ticks[1:2],n))-major.ticks[1]
  minors <- minors[-c(1,n)]

  minor.ticks = c(outer(minors,major.ticks,`+`))
  minor.ticks <- minor.ticks[minor.ticks > mn & minor.ticks < mx]


  axis(ax,at=minor.ticks,tcl=par("tcl")*t.ratio,labels=FALSE)
}

The x axis labels in the first plot on this page is in error. The minor ticks are not properly distributed.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!