geom_raster中值的范围内的非线性颜色分布 [英] Non-linear color distribution over the range of values in a geom_raster

查看:149
本文介绍了geom_raster中值的范围内的非线性颜色分布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临以下问题:一些极端值正在支配我的 geom_raster 图的色阶。一个例子可能更清晰(注意这个例子只适用于最近的ggplot2版本,我使用0.9.2.1):

  library(ggplot2)
library(reshape)
theme_set(theme_bw())
$ b m_small_sd = melt(matrix(rnorm(10000),100,100))
(样本(nrow(m_small_sd),nrow(m_big_sd)),c(x1,x2)和m_big_sd = )]
m_big_sd [c(X1,X2)] = new_xy
m = data.frame(rbind(m_small_sd,m_big_sd))
names(m)= c(x ,y,fill)

ggplot(m,aes_auto(m))+ geom_raster()+ scale_fill_gradient2()



现在我通过设置某个分位数值等于分位数来解决这个问题:

  qn =分位数(m $ fill,c(0.01,0.99),na.rm = TRUE)
m = within(m,{fill = ifelse(fill fi ll = ifelse(填充> qn [2],qn [2],fill)})



这并不是真正的最佳解决方案。我想要做的是将颜色与数值范围进行非线性映射,即在观察点更多的区域出现更多颜色。在 spplot 中,我可以使用 classInt 包中的 classIntervals 计算合适的类边界:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ =〜x + y
col = c(#EDF8B1,#C7E9B4,#7FCDBB,#41B6C4,
#1D91C0,#225EA8,#0C2C84 ,#5A005A)
at = classIntervals(m $ fill,n = length(col)+1)$ brks $ b $ spplot(m,at = at,col.regions = col)


据我所知,这是不可能的颜色映射到类间隔,像我可以在 spplot 。我可以转换 fill 轴,但是因为 fill 变量中有负值,所以不起作用。 p>

所以我的问题是:使用ggplot2有没有解决这个问题的解决方案? 解决方案

看起来ggplot(0.9.2.1)和scale(0.2.2)带来了所有你需要的东西(用于原始的 m ):

  library(比例)

qn =分位数(m $ fill,c(0.01,0.99),na.rm = TRUE)
qn01 < - rescale(c(qn,range(m $ fill)))

ggplot(m,aes(x = x,y = y,fill = fill))+
geom_raster()+
scale_fill_gradientn(
colors = colorRampPalette(c(darkblue,white,darkred))(20),
values = c(0, seq(qn01 [1],qn01 [2],length.out = 18),1))+
theme(legend.key.height = unit(4.5,lines))


I'm faced with the following problem: a few extreme values are dominating the colorscale of my geom_raster plot. An example is probably more clear (note that this example only works with a recent ggplot2 version, I use 0.9.2.1):

library(ggplot2)
library(reshape)
theme_set(theme_bw())

m_small_sd = melt(matrix(rnorm(10000), 100, 100))
m_big_sd = melt(matrix(rnorm(100, sd = 10), 10, 10))
new_xy = m_small_sd[sample(nrow(m_small_sd), nrow(m_big_sd)), c("X1","X2")]
m_big_sd[c("X1","X2")] = new_xy
m = data.frame(rbind(m_small_sd, m_big_sd))
names(m) = c("x", "y", "fill")

ggplot(m, aes_auto(m)) + geom_raster() + scale_fill_gradient2()

Right now I solve this by setting the values over a certain quantile equal to that quantile:

qn = quantile(m$fill, c(0.01, 0.99), na.rm = TRUE)
m = within(m, { fill = ifelse(fill < qn[1], qn[1], fill)
                fill = ifelse(fill > qn[2], qn[2], fill)})

This does not really feel like an optimal solution. What I would like to do is have a non-linear mapping of colors to the range of values, i.e. more colors present in the area with more observations. In spplot I could use classIntervals from the classInt package to calculate the appropriate class boundaries:

library(sp)
library(classInt)
gridded(m) = ~x+y
col = c("#EDF8B1", "#C7E9B4", "#7FCDBB", "#41B6C4", 
        "#1D91C0", "#225EA8", "#0C2C84", "#5A005A")
at = classIntervals(m$fill, n = length(col) + 1)$brks
spplot(m, at = at, col.regions = col)

To my knowledge it is not possible to hardcode this mapping of colors to class intervals like I can in spplot. I could transform the fill axis, but as there are negative values in the fill variable that will not work.

So my question is: are there any solutions to this problem using ggplot2?

解决方案

Seems that ggplot (0.9.2.1) and scales (0.2.2) bring all you need (for your original m):

library(scales)

qn = quantile(m$fill, c(0.01, 0.99), na.rm = TRUE)
qn01 <- rescale(c(qn, range(m$fill))) 

ggplot(m, aes(x = x, y = y, fill = fill)) + 
   geom_raster() + 
   scale_fill_gradientn (
      colours = colorRampPalette(c("darkblue", "white", "darkred"))(20),
      values = c(0, seq(qn01[1], qn01[2], length.out = 18), 1)) +
   theme(legend.key.height = unit (4.5, "lines"))

这篇关于geom_raster中值的范围内的非线性颜色分布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆