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

蹲街弑〆低调 提交于 2019-12-11 12:26:18

问题


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?


回答1:


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




回答2:


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)


来源:https://stackoverflow.com/questions/34796231/how-make-the-x-axis-a-base-2-logarithm-in-r-with-magicaxis

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