使用scale_fill_gradientn()将颜色比例转换为概率转换的颜色分布

时间:2016-08-10 13:23:52

标签: r ggplot2

我正在尝试将重尾的栅格数据可视化,我希望颜色的非线性映射到值的范围。有几个类似的问题,但它们并没有真正解决我的具体问题(见下面的链接)。

library(ggplot2)
library(scales)

set.seed(42)
dat <- data.frame(
   x = floor(runif(10000, min=1, max=100)),
   y = floor(runif(10000, min=2, max=1000)),
   z = rlnorm(10000, 1, 1) )

# colors for the colour scale:   
col.pal <- colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan", "#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"))
fill.colors <- col.pal(64)

如果没有以某种方式进行转换,这就是数据的样子:

ggplot(dat, aes(x = x, y = y, fill = z)) +
   geom_tile(width=2, height=30) +
   scale_fill_gradientn(colours=fill.colors) 

enter image description here 我的问题是一个与之相关的后续问题 this onethis one,给定here的解决方案实际上会产生我想要的情节,除了图例:

qn <- rescale(quantile(dat$z, probs=seq(0, 1, length.out=length(fill.colors))))
ggplot(dat, aes(x = x, y = y, fill = z)) + 
   geom_tile(width=2, height=30) +
   scale_fill_gradientn(colours=fill.colors, values = qn)

enter image description here

现在我希望图例中的色标表示值的非线性分布(现在只有比例的红色部分可见),即图例也应该基于分位数。有没有办法实现这个目标?

我认为颜色范围内的trans参数可能会按照建议here执行操作,但是会抛出错误,我认为因为qnorm(pnorm(dat$z))会产生一些无限的值(I虽然没有完全理解这个功能..)。

norm_trans <- function(){
   trans_new('norm', function(x) pnorm(x), function(x) qnorm(x)) 
}
ggplot(dat, aes(x = x, y = y, fill = z)) + 
   geom_tile(width=2, height=30) +
   scale_fill_gradientn(colours=fill.colors, trans = 'norm')
> Error in seq.default(from = best$lmin, to = best$lmax, by = best$lstep) : 'from' must be of length 1

那么,是否有人知道如何在图例中的图中使用基于分位数的颜色分布?

1 个答案:

答案 0 :(得分:2)

此代码将通过pnorm转换进行手动中断。这就是你要追求的吗?

>>> np.dstack((x.ravel(), y.ravel()))[0]
array([[1, 5],
       [2, 2],
       [3, 5],
       [3, 1],
       [4, 1],
       [5, 1],
       [5, 2],
       [7, 2],
       [8, 2]])
>>> 
>>> 
>>> np.array((x.ravel(), y.ravel())).T
array([[1, 5],
       [2, 2],
       [3, 5],
       [3, 1],
       [4, 1],
       [5, 1],
       [5, 2],
       [7, 2],
       [8, 2]])