如何使用ggplot2制作热力图?

15

我正在尝试使用ggplot2生成一个热力图。我发现了这个示例,基本上我正在尝试使用我的数据复制它,但我遇到了困难。我的数据是一个简单的.csv文件,看起来像这样:

people,apple,orange,peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0

我想要制作一个简单的热力图,其中水果名称在x轴上,人名在y轴上。该图应该呈现出每个正方形的颜色表示水果数量。与mike:peach对应的正方形应该最暗。

这是我用来尝试制作热力图的代码:

data <- read.csv("/Users/bunsen/Desktop/fruit.txt", head=TRUE, sep=",")
fruit <- c(apple,orange,peach)
people <- data[,1]
(p <- ggplot(data, aes(fruit, people)) + geom_tile(aes(fill = rescale), colour = "white") +    scale_fill_gradient(low = "white", high = "steelblue"))
当我绘制这些数据时,我得到的是水果数量在x轴上,人数在y轴上。我也没有得到代表水果数量的颜色渐变。如何让水果名称显示在x轴上,并将一个人吃的水果数量显示为热力图?在R中,我得到的当前输出如下所示:

enter image description here

2个回答

33
坦白说,@dr.bunsen - 你上面的例子难以重现,并且你没有阅读教程的第一部分,该部分通过链接提供。这里可能是你正在寻找的内容:
 library(reshape)
 library(ggplot2)
 library(scales)

 data <- structure(list(people = structure(c(2L, 3L, 1L, 4L), 
                                           .Label = c("bill", "mike", "sue", "ted"), 
                                           class = "factor"), 
                        apple = c(1L, 0L, 3L, 1L), 
                        orange = c(0L, 0L, 3L, 1L), 
                        peach = c(6L, 1L, 1L, 0L)), 
                    .Names = c("people", "apple", "orange", "peach"),
                    class = "data.frame", 
                    row.names = c(NA, -4L))
 data.m <- melt(data)
 data.m <- ddply(data.m, .(variable), transform, rescale = rescale(value))
 p <- ggplot(data.m, aes(variable, people)) + 
         geom_tile(aes(fill = rescale), colour = "white") 
 p + scale_fill_gradient(low = "white", high = "steelblue")

输入图像描述


@GeekOnAcid 我尝试使用原始问题中的数据运行上面的代码,但出现了错误:Error in rescale(value) : Usage: rescale(x,newrange),其中x是数字对象,newrange是新的最小值和最大值。问题出在哪里? - Ali
1
@AliSharifi 是的,你说得对 - ggplot2 和其他包肯定有一些变化,删除了 recale 函数或将其转移到其他函数中。你需要使用 scales 包中的 rescale 函数,将数字向量重新缩放为指定的最小值和最大值。我已更新代码以实现完全可重复性。 - Geek On Acid

1
七年后,正确格式化数据的最佳方法是使用 tidyr 而不是 reshape
使用 tidyr 中的 gather,非常容易重新格式化数据以获得预期的三列(person 为 y 轴,fruit 为 x 轴,count 为值):
library("dplyr")
library("tidyr")

hm <- readr::read_csv("people,apple,orange,peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0")

hm <- hm %>%
  gather(fruit, count, apple:peach)
  #syntax: key column (to create), value column (to create), columns to gather (will become (key, value) pairs)

数据现在看起来像这样:

# A tibble: 12 x 3
   people fruit  count
   <chr>  <chr>  <dbl>
 1 mike   apple      1
 2 sue    apple      0
 3 bill   apple      3
 4 ted    apple      1
 5 mike   orange     0
 6 sue    orange     0
 7 bill   orange     3
 8 ted    orange     1
 9 mike   peach      6
10 sue    peach      1
11 bill   peach      1
12 ted    peach      0

太好了!让我们开始绘图吧。使用ggplot2绘制热图的基本几何图形是geom_tile,我们将为其提供美学xyfill

library("ggplot2")
ggplot(hm, aes(x=x, y=y, fill=value)) + geom_tile() 

first attempt

好的,还不错,但我们可以做得更好。

  • 对于热力图,我喜欢使用黑白主题theme_bw(),可以去掉灰色背景。
  • 我也喜欢使用RColorBrewer中的调色板(使用direction=1来获取较高值的深色,否则为-1)。有很多可用的调色板:Reds、Blues、Spectral、RdYlBu(红黄蓝)、RdBu(红蓝)等。下面我使用了“Greens”。运行RColorBrewer::display.brewer.all()来查看调色板的外观。

  • 如果你想要正方形的瓷砖,只需使用coord_equal()

  • 我经常发现图例没有用处,但这取决于你特定的用例。你可以用guides(fill=F)隐藏fill图例。

  • 你可以使用geom_text(或geom_label)在瓷砖上方打印值。它需要美学xylabel,但在我们的情况下,xy是继承的。你还可以通过传递size=count作为美学将更高的值打印得更大——在这种情况下,你还需要传递size=Fguides来隐藏大小图例。

  • 你可以通过向geom_tile传递一个color来在瓷砖周围绘制线条。

把所有东西放在一起:
ggplot(hm, aes(x=fruit, y=people, fill=count)) +
  # tile with black contour
  geom_tile(color="black") + 
  # B&W theme, no grey background
  theme_bw() + 
  # square tiles
  coord_equal() + 
  # Green color theme for `fill`
  scale_fill_distiller(palette="Greens", direction=1) + 
  # printing values in black
  geom_text(aes(label=count), color="black") +
  # removing legend for `fill` since we're already printing values
  guides(fill=F) +
  # since there is no legend, adding a title
  labs(title = "Count of fruits per person")

Final heatmap

要移除任何内容,只需删除对应的行。


假设 xyfill 已被替换为 ggplot(hm, aes(x = fruit, y = people, fill = count)) - Colin D

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