Plain code version
library(scales)
## log_breaks is crazy!
log_breaks(n=3)(c(1, 1.2))
## [1] 1 10
log_breaks(n=4)(c(1, 1.2))
## [1] 1.00 1.05 1.10 1.15 1.20
## axisTicks is clunky, and gets carried away!
axisTicks(nint=4, log=TRUE, usr=log(c(1, 20)))
## [1] 1 2 5 10 20 50 100 200 500
## The best I can do for now.
limBreaks <- function(v, n=5){
b <- axisTicks(nint=n, log=TRUE, usr=range(v))
upr <- min(b[log(b)>=max(v)])
lwr <- max(b[log(b)<=min(v)])
## print(c(lwr=lwr, upr=upr))
return(b[(b>=lwr) & (b<=upr)])
}
divmultbreaks <- function(v, n=6, nmin=3, anchor=TRUE){
if (anchor) v <- unique(c(v, 1))
v <- log(v)
neg <- min(v)
if (neg==0) return(limBreaks(v, n))
pos <- max(v)
if (pos==0) return(1/limBreaks(-v, n))
flip <- -neg
big <- pmax(pos, flip)
small <- pmin(pos, flip)
bigprop <- big/(pos + flip)
bigticks <- ceiling(n*bigprop)
main <- limBreaks(c(0, big), bigticks)
cut <- pmin(bigticks, 1+sum(main<small))
if(cut<nmin)
other <- limBreaks(c(0, small), nmin)
else
other <- main[1:cut]
breaks <- c(main, 1/other)
if (flip > pos) breaks <- 1/breaks
return(sort(unique(breaks)))
}
divmultbreaks(c(11))
## [1] 1 2 5 10 20
divmultbreaks(c(0.04))
## [1] 1.00 0.20 0.10 0.02
divmultbreaks(c(0.04, 11))
## [1] 0.02 0.10 0.20 1.00 2.00 5.00 10.00 20.00
divmultbreaks(c(0.02, 2))
## [1] 0.02 0.10 0.20 1.00 2.00
divmultbreaks(c(0.8, 20))
## [1] 0.7142857 0.8333333 1.0000000 2.0000000 5.0000000 10.0000000 20.0000000
y <- (exp(seq(-2,5,0.2)))
range(y)
## [1] 0.1353353 148.4131591
divmultbreaks(y)
## [1] 1e-01 2e-01 5e-01 1e+00 1e+01 1e+02 1e+03