ggplot2正负值不同颜色渐变

7

我正在使用R (3.0.1)和ggplot2 (0.9.3.1)。我有一些包含正数和负数的数据,并且想要得到一个geom_tile图,其中正数和负数有不同的颜色渐变(例如,正数从红到黄,负数从蓝到青)。我可以使用scale_fill_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)))

正是我想做的事情... - marsl
请查看此线程:链接。其中有一个在同一图表中使用两个比例渐变的示例。 - Niels Janssen
3个回答

12

我不确定这个功能是在哪个版本的ggplot2中添加的,但现在已经内置了此功能:

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

感谢指出该函数的存在,这使得事情变得更容易了! - Maxim.K
1
scale_fill_gradient2并不是新的;它在1.0版本之前就已经存在了。对于需要指定中点/零颜色的简单问题,它运作良好。然而,它从高到中点再到低提供了平滑的过渡。原始问题不仅仅想要中点为白色,还希望在用于正数和负数的颜色刻度之间有一个有效的断点(这样稍微为正的值就不会只比白色略微不同)。这就是为什么我基于scale_fill_gradientn创建了一个答案的原因。 - Brian Diggs

11

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

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

在这里输入图像描述

指南书本身没有物理断点,但颜色分布符合您的描述。


1
提醒所有其他搜索者:下面Keith的答案反映了新的ggplot2函数,可以自动和干净地完成此操作。 - Will
@Will scale_fill_gradient2不是一个新函数;它从一开始就存在了。然而,它并不能完全满足问题的要求。 - Brian Diggs

2

在绘制图表时,您可以始终将结果略微填充,以避免仅显示白色范围,并且仅显示接近0的数字的浅黄色和浅青色:

dat$Y2 <- ifelse(dat$Y > 0, dat$Y + .25, ifelse(dat$Y < 0, dat$Y-.25,dat$Y))

谢谢您的评论,但我不明白这如何解决在零点处具有连续区域的问题,而我想在零点处有一个离散的断点。 - Niels Janssen
只有当Y值在0的某个范围内(我不确定确切的范围,但±.25在这里可以正常工作)时,方框才会被涂成白色。您可以通过将所有点移动一个小常数远离0来消除任何白色方框。原来为-.0001的方框现在将变为-.2501,并显示为浅青色而不是白色。 - thompsor
谢谢你的帮助,确实有效。不幸的是,对于我的项目,我不能像你建议的那样更改这些值。 - Niels Janssen
Brian Diggs的回答正是我一直在尝试寻找的方法,但我无法完全弄清楚。他的解决方案绝对是更可取的。 - thompsor

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