简体   繁体   中英

How make the x-axis a base-2 logarithm in R with magicaxis?

Magicaxis lets you unlog an axis:

library(magicaxis)
plot(1:10, 1:10, axes=FALSE)
magaxis(unlog='x')

But this assumes a base 10 logarithm. How can you specify a different base?

author of magicaxis here. The new pre-CRAN version on my GitHub (asgr/magicaxis) has the new feature of specifying the log base. You can install this straight from GitHub using devtools. The argument is called powbase and defaults to 10. Let me know how this works for you.

Aaron

The only part of the code the calls a log or and "un-log" seems to be hard coded to use 10^ or the function log10(). So there seems to be no way to tell the function to use a different base.

function (side = 1:2, majorn = 5, minorn = 5, tcl = 0.5, ratio = 0.5, 
  labels = TRUE, unlog = "Auto", mgp = c(2, 0.5, 0), mtline = 2, 
  xlab = NULL, ylab = NULL, crunch = TRUE, logpretty = TRUE, 
  prettybase = 10, hersh = FALSE, family = "sans", frame.plot = FALSE, 
  usepar = FALSE, ...) 
{
  majornlist = majorn
  minornlist = minorn
  unloglist = unlog
  labelslist = labels
  crunchlist = crunch
  logprettylist = logpretty
  prettybaselist = prettybase
  if (length(majorn) == 1 & length(side) > 1) {
    majornlist = rep(majorn, length(side))
  }
  if (length(minorn) == 1 & length(side) > 1) {
    minornlist = rep(minorn, length(side))
  }
  if (length(unlog) == 1 & length(side) > 1 & (unlog[1] == 
    T | unlog[1] == F | unlog[1] == "Auto")) {
    unloglist = rep(unlog, length(side))
  }
  if (length(labels) == 1 & length(side) > 1) {
    labelslist = rep(labels, length(side))
  }
  if (length(crunch) == 1 & length(side) > 1) {
    crunchlist = rep(crunch, length(side))
  }
  if (length(logpretty) == 1 & length(side) > 1) {
    logprettylist = rep(logpretty, length(side))
  }
  if (length(prettybase) == 1 & length(side) > 1) {
    prettybaselist = rep(prettybase, length(side))
  }
  if (unlog[1] == "x") {
    unloglist = rep(FALSE, length(side))
    unloglist[side %in% c(1, 3)] = TRUE
  }
  if (unlog[1] == "y") {
    unloglist = rep(FALSE, length(side))
    unloglist[side %in% c(2, 4)] = TRUE
  }
  if (unlog[1] == "xy" | unlog[1] == "yx") {
    unloglist = rep(TRUE, length(side))
  }
  if (length(majornlist) != length(side)) {
    stop("Length of majorn vector mismatches number of axes!")
  }
  if (length(minornlist) != length(side)) {
    stop("Length of minorn vector mismatches number of axes!")
  }
  if (length(unloglist) != length(side)) {
    stop("Length of unlog vector mismatches number of axes!")
  }
  if (length(labelslist) != length(side)) {
    stop("Length of labels vector mismatches number of axes!")
  }
  if (length(crunchlist) != length(side)) {
    stop("Length of crunch vector mismatches number of axes!")
  }
  if (length(logprettylist) != length(side)) {
    stop("Length of logpretty vector mismatches number of axes!")
  }
  if (length(prettybaselist) != length(side)) {
    stop("Length of prettybase vector mismatches number of axes!")
  }
  currentfamily = par("family")
  if (hersh & family == "serif") {
    par(family = "HersheySerif")
  }
  if (hersh & family == "sans") {
    par(family = "HersheySans")
  }
  if (hersh == F & family == "serif") {
    par(family = "serif")
  }
  if (hersh == F & family == "sans") {
    par(family = "sans")
  }
  if (usepar) {
    tcl = par()$tcl
    mgp = par()$mgp
  }
  for (i in 1:length(side)) {
    currentside = side[i]
    majorn = majornlist[i]
    minorn = minornlist[i]
    unlog = unloglist[i]
    labels = labelslist[i]
    crunch = crunchlist[i]
    logpretty = logprettylist[i]
    prettybase = prettybaselist[i]
    lims = par("usr")
    if (currentside %in% c(1, 3)) {
      lims = lims[1:2]
      if (par("xlog")) {
        logged = T
      }
      else {
        logged = F
      }
    }
    else {
      lims = lims[3:4]
      if (par("ylog")) {
        logged = T
      }
      else {
        logged = F
      }
    }
    lims = sort(lims)
    if (unlog == "Auto") {
      if (logged) {
        unlog = T
      }
      else {
        unlog = F
      }
    }
    if (logged | unlog) {
      usemultloc = (10^lims[2])/(10^lims[1]) < 50
    }
    else {
      usemultloc = F
    }
    if (unlog) {
      sci.tick = maglab(10^lims, n = majorn, log = T, 
        exptext = T, crunch = crunch, logpretty = logpretty, 
        usemultloc = usemultloc, prettybase = prettybase, 
        hersh = hersh)
      major.ticks = log10(sci.tick$tickat)
      uselabels = sci.tick$exp
      labloc = log10(sci.tick$labat)
      if (usemultloc == F) {
        minors = log10(pretty(10^major.ticks[1:2], minorn + 
          2)) - major.ticks[1]
      }
    }
    if (logged & unlog == F) {
      sci.tick = maglab(10^lims, n = majorn, log = T, 
        exptext = F, crunch = crunch, logpretty = logpretty, 
        usemultloc = usemultloc, prettybase = prettybase, 
        hersh = hersh)
      major.ticks = log10(sci.tick$tickat)
      uselabels = sci.tick$exp
      labloc = log10(sci.tick$labat)
      if (usemultloc == F) {
        minors = log10(pretty(10^major.ticks[1:2], minorn + 
          2)) - major.ticks[1]
      }
    }
    if (logged == F & unlog == F) {
      sci.tick = maglab(lims, n = majorn, log = F, exptext = F, 
        prettybase = prettybase, hersh = hersh)
      major.ticks = sci.tick$tickat
      uselabels = sci.tick$exp
      labloc = sci.tick$labat
      minors = pretty(major.ticks[1:2], minorn + 2) - 
        major.ticks[1]
    }
    if (logged) {
      axis(side = currentside, at = 10^major.ticks, tcl = tcl, 
        labels = FALSE, mgp = mgp, ...)
    }
    else axis(side = currentside, at = major.ticks, tcl = tcl, 
      labels = FALSE, mgp = mgp, ...)
    if (labels) {
      if (logged) {
        axis(side = currentside, at = 10^labloc, tick = F, 
          labels = uselabels, mgp = mgp, ...)
      }
      else axis(side = currentside, at = labloc, tick = F, 
        labels = uselabels, mgp = mgp, ...)
    }
    if (usemultloc == F) {
      minors = minors[-c(1, length(minors))]
      minor.ticks = c(outer(minors, major.ticks, `+`))
      if (logged) {
        axis(currentside, at = 10^minor.ticks, tcl = tcl * 
          ratio, labels = FALSE, ...)
      }
      else axis(currentside, at = minor.ticks, tcl = tcl * 
        ratio, labels = FALSE, ...)
    }
    if (is.null(xlab) == F & currentside == 1) {
      mtext(xlab, 1, line = mtline)
    }
    if (is.null(ylab) == F & currentside == 2) {
      mtext(ylab, 2, line = mtline)
    }
  }
  if (frame.plot) {
    box()
  }
  par(family = currentfamily)
}

You could try modifying the code to use a parameter for the base and log instead of log10() but this can get messy especially if the parts of magicaxis call each other.

Without magicaxis:

x <- 1:10
y <- 1:10
base <- 2
plot(x,y,axes=FALSE)
axis(1,at=x,labels = base^(x))
axis(2,at=y)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM