geom_raster中值的范围内的非线性颜色分布 [英] Non-linear color distribution over the range of values in a 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屋!