R ggplot2正负值不同的颜色渐变

R ggplot2正负值不同的颜色渐变,r,ggplot2,R,Ggplot2,我使用的是R(3.0.1)和ggplot2(0.9.3.1)。我有包含正值和负值的数据,我想获得一个geom_tile图,其中正数和负数有不同的色阶梯度(例如,正数从红色变为黄色,负数从蓝色变为青色)。我可以使用scale\u fill\u gradientn(见下文)来接近我想要的效果,但这会导致一个连续的渐变,在中点(0)处包含“白色”。我需要避免这些中点颜色,因此需要以某种方式在零处“打破”渐变。换句话说,我需要两个连续的渐变(一个用于正值,一个用于负值),它们在零处有一个离散的中断。有什

我使用的是R(3.0.1)和ggplot2(0.9.3.1)。我有包含正值和负值的数据,我想获得一个geom_tile图,其中正数和负数有不同的色阶梯度(例如,正数从红色变为黄色,负数从蓝色变为青色)。我可以使用scale\u fill\u gradientn(见下文)来接近我想要的效果,但这会导致一个连续的渐变,在中点(0)处包含“白色”。我需要避免这些中点颜色,因此需要以某种方式在零处“打破”渐变。换句话说,我需要两个连续的渐变(一个用于正值,一个用于负值),它们在零处有一个离散的中断。有什么帮助吗

dat <- data.frame(Row = rep(x = LETTERS[1:5], times = 10)
 , Col = rep(x = LETTERS[1:10], each = 5)
 , Y = runif(n = 50, min = -1, max = 1))

p <- ggplot(data =  dat, aes(x = Row, y = Col)) + 
  geom_tile(aes(fill = Y)) +
  scale_fill_gradientn(colours=c("blue","cyan","white", "yellow","red"), values=rescale(c(-1,0,1)))

dat在绘制图形时,您始终可以将结果填充一点,以避免完全显示白色范围,并且仅显示0左右数字的浅黄色和浅青色:

dat$Y2 <- ifelse(dat$Y > 0, dat$Y + .25, ifelse(dat$Y < 0, dat$Y-.25,dat$Y))
dat$y20,dat$Y+.25,如果其他(dat$Y<0,dat$Y-.25,dat$Y))

使青色和黄色之间的范围非常小:

ggplot(data =  dat, aes(x = Row, y = Col)) + 
  geom_tile(aes(fill = Y)) +
  scale_fill_gradientn(colours=c("blue","cyan","white", "yellow","red"), 
    values=rescale(c(-1,0-.Machine$double.eps,0,0+.Machine$double.eps,1)))


指南中没有物理中断,但颜色映射如您所述。

我不确定添加了哪个版本的ggplot2,但现在有用于此的内置功能:

p <- ggplot(data =  dat, aes(x = Row, y = Col)) + 
    geom_tile(aes(fill = Y)) +
    scale_fill_gradient2()

p感谢您的评论,但我不明白这是如何解决在零上有一个连续区域的问题,而我希望在零上有一个离散的断点。只有当Y值在0的某个范围内时(我不确定确切的范围,但是±.25在这里很好)。只需将所有点从0移动一个小常量,就不会再有任何白框。原来为-0.0001的框现在将为-0.2501,并显示为浅青色而不是白色。感谢您的帮助,确实有效。不幸的是,对于我的项目,我不能像你建议的那样改变这些值。Brian Diggs的答案是我试图找到一种方法来做什么,但无法完全弄清楚。他的解决方案绝对是可取的。这正是我想做的…检查此线程:。有一个在同一个图形中使用两个比例梯度的示例。感谢您指出该函数的存在,使事情变得更简单<代码>比例填充梯度2
不是新的;它在1.0版之前就已经可用了。对于需要指定中点/零颜色的简单问题,它可以很好地工作。但是,它提供了从高点到中点到低点的平滑过渡。最初的问题不只是希望中点是白色,而是希望在用于正片和负片的色阶之间有一个有效的分界(因此,一点正片不仅仅与白色有一点不同)。这就是为什么我创建了一个基于
scale\u fill\u gradientn
.FYI的答案,供所有其他搜索者参考:下面Keith的答案反映了新的ggplot2功能,该功能可以自动和cleanly@Will
scale\u fill\u gradient2
不是一个新功能;它从一开始就在那里。然而,它并不完全满足问题的要求。