在geom_raster中,数值范围内的非线性颜色分布

18
我面临以下问题:一些极端值支配着我的geom_raster图的颜色比例尺。一个示例可能更清楚(请注意,此示例仅适用于最近的ggplot2版本,我使用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()

enter image description here

现在我通过将超过某个分位数的值设置为该分位数来解决这个问题:

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)})

enter image description here

这不是最优解决方案。我想要做的是将颜色非线性映射到值范围,即在具有更多观测值的区域中存在更多颜色。在spplot中,我可以使用classInt包中的classIntervals计算适当的类边界:

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)

enter image description here

据我所知,无法像在spplot中那样硬编码颜色到类间的映射。我可以转换fill轴,但由于fill变量中存在负值,这种方法行不通。因此,我的问题是:是否有使用ggplot2解决此问题的方法?

我刚刚注意到这个问题,所以我会添加一个链接到我之前提出的相关查询:https://dev59.com/h3XYa4cB1Zd3GeqP4ELB - baptiste
1个回答

21

看起来ggplot(0.9.2.1)和scales(0.2.2)都提供了你需要的一切(针对你原来的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"))

结果图


1
我本来想指出你可以使用任何所需的缩放来构建自己的颜色调色板,但这看起来是远远更简单的方法。 - Carl Witthoft
@CarlWitthoft:我以前也这样做,但后来我不得不查找scale_fill_gradientn的帮助(因为我试图将颜色放入“values”中)... - cbeleites unhappy with SX
1
痛苦啊!我希望能看到一个scale_*_gradient函数,它只需要取值和颜色,并进行插值。 - Spacedman
1
@Spacedman:告诉Hadley,使用trim_quantiles参数来扩展scales时,我向他表示+1...;-) - cbeleites unhappy with SX
+1 这太棒了。scales 有很多有用的方法,例如 scales::gradient_n_pal(...) 和转换方法,例如 log1p_trans, squish_infinite - smci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接