R中levelplot的颜色

3
我有以下代码。它生成一个levelplot,其中小于0的方块值应该以红色调着色,大于0的方块值应该以蓝色调着色。然后我想让值为0的正方形变成白色。但是,没有什么东西最终变成了白色。我该如何修复这个问题? 那第一列中的三个正方形都应该是白色的。
library(lattice)

cc = colorRampPalette( c("red", "white","blue"))
trellis.par.set(regions=list(col=cc(20)))
x = c(1,2,3,1,2,3,1,2,3)
y = c(1,1,1,2,2,2,3,3,3)
z = c(0,-2,-3,0,2,3,0,1,-1)
df = data.frame(x,y,z)
p <- levelplot(z~x*y, df,
               panel=function(...) {
                 arg <- list(...)
                 panel.levelplot(...)
                 })
print(p)

enter image description here


更新: 这里有一个可重复的示例,试图修复它,但仍不太正确: 这是一个数据框 df

    x y           z
1   1 1 -0.17457167
2   2 1  0.93407856
3   3 1  0.55129545
4   4 1  0.97388216
5   5 1 -1.00000000
6   6 1  0.52883410
7   7 1 -1.00000000
8   8 1  0.85112829
9   9 1 -1.00000000
10 10 1  1.00000000
11 11 1 -0.87714166
12 12 1  1.00000000
13 13 1 -0.95403260
14 14 1  1.00000000
15 15 1 -0.91600501
16 16 1  1.00000000
17 17 1 -1.00000000
18 18 1 -0.38800669
19 19 1 -0.52110322
20 20 1  0.00000000
21 21 1 -0.08211450
22 22 1  0.55390723
23 23 1  1.00000000
24 24 1 -0.04147514
25 25 1 -1.00000000
26 26 1 -0.39751358
27 27 1 -0.99550773
28 28 1  0.00000000
29 29 1  0.20737568
30 30 1  0.00000000
31 31 1  0.00000000
32 32 1  0.00000000
33 33 1 -0.26702883

接下来是代码:

cc = colorRampPalette( c("red", "white","blue"))
trellis.par.set(regions=list(col=cc(21)))
zrng <- range(z)       # what's the range of z
tol <- 1e-2            # what tolerance is necessary?
colorBreaks <- c(
  seq(zrng[1] - 0.01, 0 - tol, length.out = 11),
  seq(0 + tol,zrng[2] + 0.01,length.out = 10))  
p <- levelplot(z~x*y, df, 
               at = colorBreaks,
               panel=function(...) {
                 arg <- list(...)
                 panel.levelplot(...)
               })
print(p)

它生成了这个图,但是光谱中没有白色的插槽: enter image description here


1
指定的颜色中没有白色 - which(cc(20)=="#FFFFFF"),你需要分别从红色到白色和从白色到蓝色进行两个单独的颜色渐变。 - thelatemail
@thelatemail 谢谢,我该怎么做? - CodeGuy
1个回答

2
如thelatemail所指出的那样,cc(20)永远不会产生白色("#FFFFFF")。你必须使用奇数来准确地表示颜色坡道的中间值(查看cc(3)与cc(4))。
现在,您需要设置levelplot的at参数,以设置颜色的断点。默认值为at = pretty(z):
#[1] -3 -2 -1  0  1  2  3

但您不希望0成为断点。您希望它有自己的颜色,并与颜色条中心对齐。

您可以通过将断点设置得尽可能接近0(在某些tol内)来实现这一点,以防止任何其他值映射到白色。大致思路是留出一个小空间给0,可以通过如下方法实现:at = c(seq(-3.01, -0.00001, length.out = 11), seq(0.00001, 3.01, length.out = 11)) 或者使用下面展示的类似方法。由于颜色条具有奇数个值,所以序列需要有偶数个值。(例如,三种颜色的颜色条可以分为两个断点,但四个值的颜色条可以分为三个断点。)

trellis.par.set(regions=list(col=cc(21)))

# Define a sequence of breaks for the at argument to levelplot.
zrng <- range(z)       # what's the range of z
tol <- 1e-5            # what tolerance is necessary?
colorBreaks <- c(
  seq(zrng[1] - 0.01,  # adding a small buffer on end
      0 - tol,
      length.out = 11),
  seq(0 + tol,
      zrng[2] + 0.01,
      length.out = 11))  
      # note, I chose length.out = 11.
      # Don't do more than roughly ceiling((# of colors) / 2) 


p <- levelplot(z~x*y, df, 
               at = colorBreaks,
               panel=function(...) {
                 arg <- list(...)
                 panel.levelplot(...)
                 })

enter image description here


你好,非常感谢。我尝试了不同的数据集,并添加了更多的填充,现在我得到了类似这样的结果:https://img42.com/vSz6n(它产生了期望的效果,但白色没有落在0标记处) - CodeGuy
我应该提一下,我仍在使用cc(21),它确实会产生#FFFFFF,但是颜色谱中没有白色。 - CodeGuy
@CodeGuy 我明白了。你传递给 at 的参数需要包含偶数个值,这样0才能处于中间位置。如果不是偶数,就没有“中间”位置。所以,将 length.out = 10length.out = 11 改为其中一个,这样序列就有偶数个条目。如果你的光谱中有4种颜色,则有3个(或5个,包括极端值)断点。对于奇数,比如21,你需要偶数个断点。 - Jota
谢谢!那个有效。所以你的例子也需要修改吗? - CodeGuy

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