How to get something like Matplotlib character scale in ggplot or grid?

For very heavy tails, both positive and negative, I sometimes like to see all the data on the graph without hiding the structure in a single interval.

When plotting using Matplotlib in Python, I can do this by selecting a character scale that uses a logarithmic transformation outside some interval and linear plotting inside it.

Earlier in R, I built this behavior by converting data using arcsinh on a one-time basis. However, tag labels, etc. It is very difficult to do it right (see below). enter image description here

Now I came across a bunch of data, where a subset in a grid or ggplot would be very convenient. I don’t want to use Matplotlib because of the subset, but I’m sure I’m missing a symbol!

Edit:

I see that ggplot uses a package called scales , which solves a lot of this problem (if it works). Automatic selection of labeling and label placement still looks rather complicated, albeit beautiful. Perhaps some combination of log_breaks and cbreaks ?

Edit 2:

The following code is not too bad

 sinh.scaled <- function(x,scale=1){ sinh(x)*scale } asinh.scaled <- function(x,scale=1) { asinh(x/scale) } asinh_breaks <- function (n = 5, scale = 1, base=10) { function(x) { log_breaks.callable <- log_breaks(n=n,base=base) rng <- rng <- range(x, na.rm = TRUE) minx <- floor(rng[1]) maxx <- ceiling(rng[2]) if (maxx == minx) return(sinh.scaled(minx, scale=scale)) big.vals <- 0 if (minx < (-scale)) { big.vals = big.vals + 1 } if (maxx>scale) { big.vals = big.vals + 1 } brk <- c() if (minx < (-scale)) { rbrk <- log_breaks.callable( c(-min(maxx,-scale), -minx ) ) rbrk <- -rev(rbrk) brk <- c(brk,rbrk) } if ( !(minx>scale | maxx<(-scale)) ) { rng <- c(max(minx,-scale), min(maxx,scale)) minc <- floor(rng[1]) maxc <- ceiling(rng[2]) by <- floor((maxc - minc)/(n-big.vals)) + 1 cb <- seq(minc, maxc, by = by) brk <- c(brk,cb) } if (maxx>scale) { brk <- c(brk,log_breaks.callable( c(max(minx,scale), maxx ))) } brk } } asinh_trans <- function(scale = 1) { trans <- function(x) asinh.scaled(x, scale) inv <- function(x) sinh.scaled(x, scale) trans_new(paste0("asinh-", format(scale)), trans, inv, asinh_breaks(scale = scale), domain = c(-Inf, Inf)) } 
+4
source share
1 answer

A solution based on the scales package and inspired by a post by Brian Diggs mentioned by @Dennis:

 symlog_trans <- function(base = 10, thr = 1, scale = 1){ trans <- function(x) ifelse(abs(x) < thr, x, sign(x) * (thr + scale * suppressWarnings(log(sign(x) * x / thr, base)))) inv <- function(x) ifelse(abs(x) < thr, x, sign(x) * base^((sign(x) * x - thr) / scale) * thr) breaks <- function(x){ sgn <- sign(x[which.max(abs(x))]) if(all(abs(x) < thr)) pretty_breaks()(x) else if(prod(x) >= 0){ if(min(abs(x)) < thr) sgn * unique(c(pretty_breaks()(c(min(abs(x)), thr)), log_breaks(base)(c(max(abs(x)), thr)))) else sgn * log_breaks(base)(sgn * x) } else { if(min(abs(x)) < thr) unique(c(sgn * log_breaks()(c(max(abs(x)), thr)), pretty_breaks()(c(sgn * thr, x[which.min(abs(x))])))) else unique(c(-log_breaks(base)(c(thr, -x[1])), pretty_breaks()(c(-thr, thr)), log_breaks(base)(c(thr, x[2])))) } } trans_new(paste("symlog", thr, base, scale, sep = "-"), trans, inv, breaks) } 

I am not sure that the effect of the scale parameter is the same as in Python, but here are a couple of comparisons (see Python version here ):

 data <- data.frame(x = seq(-50, 50, 0.01), y = seq(0, 100, 0.01)) data$y2 <- sin(data$x / 3) # symlogx ggplot(data, aes(x, y)) + geom_line() + theme_bw() + scale_x_continuous(trans = symlog_trans()) 

enter image description here

 # symlogy ggplot(data, aes(y, x)) + geom_line() + theme_bw() scale_y_continuous(trans="symlog") 

enter image description here

 # symlog both, threshold = 0.015 for y # not too pretty because of too many breaks in short interval ggplot(data, aes(x, y2)) + geom_line() + theme_bw() scale_y_continuous(trans=symlog_trans(thr = 0.015)) + scale_x_continuous(trans = "symlog") 

enter image description here

 # Again symlog both, threshold = 0.15 for y ggplot(data, aes(x, y2)) + geom_line() + theme_bw() scale_y_continuous(trans=symlog_trans(thr = 0.15)) + scale_x_continuous(trans = "symlog") 

enter image description here

+6
source

All Articles