使用ggplot2创建带有分段值颜色的热力图

33

我想在ggplot2中制作一个热图。我的示例数据和代码如下:

set.seed(12345)
dat <- 
  data.frame(
      Row = rep(x = LETTERS[1:5], times = 10)
    , Col = rep(x = LETTERS[1:10], each = 5)
    , Y = rnorm(n = 50, mean = 0, sd = 1)
    )
library(ggplot2)
p <- ggplot(data =  dat, aes(x = Row, y = Col)) + 
      geom_tile(aes(fill = Y), colour = "white") +
      scale_fill_gradient(low = "white", high = "steelblue")
p

我想要像这样针对数值范围设置颜色方案:

-3 <= Y < -2  ---> Dark Blue
-2 <= Y < -1  ---> Blue
-1 <= Y <  0  ---> Light Blue
 0 <= Y <  1  ---> Light Green
 1 <= Y <  2  ---> Green
 2 <= Y <= 3  ---> Dark Green
2个回答

52

不清楚您是想要离散的颜色还是您列出的颜色只是Y范围内的标记。我将两者都展示。

对于离散颜色,请使用joran定义的Y1

dat$Y1 <- cut(dat$Y,breaks = c(-Inf,-3:3,Inf),right = FALSE)

然后,您可以使用手动比例尺获取具有您列出的特定颜色的图表。

p <- ggplot(data =  dat, aes(x = Row, y = Col)) + 
      geom_tile(aes(fill = Y1)) +
      scale_fill_manual(breaks=c("\[-Inf,-3)", "\[-3,-2)", "\[-2,-1)", 
                                 "\[-1,0)", "\[0,1)", "\[1,2)", 
                                 "\[2,3)", "\[3, Inf)"),
                        values = c("white", "darkblue", "blue",
                                   "lightblue", "lightgreen", "green",
                                   "darkgreen", "white"))
p

我不知道你对于-3和3之外的颜色有什么要求,所以我使用了白色。

如果你希望有一个连续的颜色,从负数的蓝色到0的白色再到正数的绿色,scale_fill_gradient2会起作用。

ggplot(data =  dat, aes(x = Row, y = Col)) + 
  geom_tile(aes(fill = Y)) +
  scale_fill_gradient2(low="darkblue", high="darkgreen", guide="colorbar")

enter image description here

如果您希望对颜色进行精细的控制,使得在数值为3时映射到“深蓝色”,在数值为2时映射到“蓝色”,在数值为1时映射到“浅蓝色”,在数值为0时映射到“白色”等,则可以使用scale_fill_gradientn函数:
library("scales")
ggplot(data =  dat, aes(x = Row, y = Col)) + 
  geom_tile(aes(fill = Y)) +
  scale_fill_gradientn(colours=c("darkblue", "blue", "lightblue", 
                                 "white",
                                 "lightgreen", "green", "darkgreen"),
                       values=rescale(c(-3, -2, -1,
                                        0,
                                        1, 2, 3)),
                       guide="colorbar")


感谢 @Brian 的精彩回答。你是 ggplot2 的巫师。非常感谢你的帮助。 - MYaseen208
尽管有40个赞,但是当我复制并粘贴Brian的scale_fill_manual方法时,它就像图中所示一样无法正常工作,这真是令人困惑。 - Agus camacho
@Aguscamacho,你有收到任何错误信息吗?我得到了一个非常清晰的错误信息,指出''是字符串中未识别的转义符。在手动“破折号”定义中去掉\可以解决问题。考虑到这个答案已经六年了,很可能代码六年前能够工作,但现在却因R或ggplot2或其他任何更新而出现错误。 - fabern

30
你有几种选择来完成这样的任务,以下是其中的一种起点。
首先,使用“cut”函数以适当的间隔从“Y”中创建一个因子:
dat$Y1 <- cut(dat$Y,breaks = c(-Inf,-3:3,Inf),right = FALSE)

然后使用来自 RColorBrewer 的调色板进行绘图:

ggplot(data =  dat, aes(x = Row, y = Col)) + 
      geom_tile(aes(fill = Y1), colour = "white") +
      scale_fill_brewer(palette = "PRGn")

图片描述

这个配色方案在低端更偏紫色,但它是我在brewer调色板中找到的最接近的颜色。

如果你想自己构建一个配色方案,你可以简单地使用scale_fill_manual并为values参数指定你所需的颜色向量。


感谢@joran的回复。我想知道如何清除绘图中两个矩形之间的线条。谢谢。 - MYaseen208
@MYaseen208 在 geom_tile 中设置 colour = "transparent" - joran

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