在ggplot2中使用矩阵值创建热图

58
我曾经看过使用不同的 R 图形系统(包括 lattice 和 base)制作的带有数值的热力图,就像这样: enter image description here 我经常使用 ggplot2 并希望能够制作一个热力图,并在相应的单元格中绘制数值。以下是热力图及使用 geom_text 的尝试:
library(reshape2, ggplot2)
dat <- matrix(rnorm(100, 3, 1), ncol=10)
names(dat) <- paste("X", 1:10)
dat2 <- melt(dat, id.var = "X1")
p1 <- ggplot(dat2, aes(as.factor(Var1), Var2, group=Var2)) +
    geom_tile(aes(fill = value)) +
    scale_fill_gradient(low = "white", high = "red") 
p1

#attempt
labs <- c(apply(round(dat[, -2], 1), 2, as.character))
p1 +  geom_text(aes(label=labs), size=1)

通常情况下,我可以确定要传递的 x 和 y 值,但在这种情况下我不知道,因为此信息未存储在数据集中。我该如何将文本放置在热力图上?


3
这个问题中有一个使用geom_tile和文本的示例,可能会很有用。将你的aes()调用从geom_tile移动到geom_text。 - SlowLearner
1
尝试使用 heatmap.2。参考类似的帖子 https://dev59.com/G2865IYBdhLWcg3wfeqU - Puriney
1
@TylerRinker 刚上公交车,无法提供恰当的答案,但很高兴看到你已经解决了问题。 - SlowLearner
1
这个有帮助吗?http://socialdatablog.com/heatmap-tables-with-ggplot2-sort-of/ - Roman Luštrik
@Puriney,在我看来,heatmap.2比ggplot2更强大,用于创建热图的选项,你同意吗?我读到了这样一句话:“ggplot2中没有特定的热图绘制函数”。来源:http://learnr.wordpress.com/2010/01/26/ggplot2-quick-heatmap-plotting/ - warship
2个回答

111

关键是向数据添加行标识符并将其“拉长”。

编辑于2022年12月,以使代码可在R 4.2.2 / ggplot2 3.4.0中重现,并反映tidyverse语义的更改。

library(ggplot2)
library(tidyverse)
dat <- matrix(rnorm(100, 3, 1), ncol = 10)
## the matrix needs names
names(dat) <- paste("X", 1:10)

## convert to tibble, add row identifier, and shape "long"
dat2 <-
  dat %>%
  as_tibble() %>%
  rownames_to_column("Var1") %>%
  pivot_longer(-Var1, names_to = "Var2", values_to = "value") %>%
  mutate(
    Var1 = factor(Var1, levels = 1:10),
    Var2 = factor(gsub("V", "", Var2), levels = 1:10)
  )
#> Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if
#> `.name_repair` is omitted as of tibble 2.0.0.
#> ℹ Using compatibility `.name_repair`.

ggplot(dat2, aes(Var1, Var2)) +
  geom_tile(aes(fill = value)) +
  geom_text(aes(label = round(value, 1))) +
  scale_fill_gradient(low = "white", high = "red")

使用 reprex v2.0.2 工具,于2022年12月31日创建。


@TylerRinker 非常感谢。我该如何升级这个图表,使其看起来像这个呢? - Pradeep
@TylerRinker:非常棒的介绍,兄弟。有没有什么提示可以让我提升游戏以使热力图看起来像http://imgur.com/gallery/X2Zxf? - Pradeep
@Pradeep 不确定,但那会很好。也许可以使用gridExtra、cowplot和/或ggtree包在顶部添加注释和/或组合图表(仅一些文本)。无论如何,这是一个新的问题,我想知道答案。你能开一个新的主题吗? - Tyler Rinker
你如何在每个数字周围添加一个小白色边框? - skan
@skan 这是一个值得开新帖讨论的新问题。有几种可能的方法可以尝试。 - Tyler Rinker
显示剩余6条评论

13

有另一种更简单的方法可以制作带值的热力图。您可以使用pheatmap来完成此操作。

dat <- matrix(rnorm(100, 3, 1), ncol=10)
names(dat) <- paste("X", 1:10)
install.packages('pheatmap') # if not installed already
library(pheatmap)
pheatmap(dat, display_numbers = T)

这将给您一个类似于以下的图表:

带数值的热力图

如果您想要移除聚类并使用自己的颜色方案,可以执行以下操作:
pheatmap(dat, display_numbers = T, color = colorRampPalette(c('white','red'))(100), cluster_rows = F, cluster_cols = F, fontsize_number = 15)

无聚类和红白颜色的热力图

您还可以更改显示数字的字体大小、格式和颜色。


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