R语言绘制热图(ggplot2包)

前言

R语言中,常用pheatmap这个R包绘制热图,但是拓展性不强,ComplexHeatmap又过于复杂。

今天分享一下如何用ggplot2绘制热图(pheatmap包也是基于ggplot2的)。方便大家熟悉ggplot2绘图体系。

pheatmap包绘制热图可以参考:https://www.r2omics.cn/docs/gallery/omicsChart/heatmap/

什么是热图?

如图,就是一副组学研究中热图的常用绘制模式,每个小方格表示每个基因在不同样本中的定量值,其颜色表示该基因表达量大小,红色为高表达,蓝色为低表达。

1,行名称,一般为样本名称

2,列名称,一般为基因名称

3,图例信息,左侧图例是热图表达量的颜色图例说明,右侧图例为分组信息的图例说明。绘制热图一般会做ZScore归一化处理,可以看到图例数据成0左右对称分布,一般都是做了Zscore归一化的。

4,列聚类,如果不聚类,排序将保持文件数据的默认方式。从样本角度讲,聚类可以观察到你采集的不同组别样本是否被分类到一起了。因为,理论上如果样本来自于同一个组,其特征应该是相似的,而如果在实际操作中,某一个应该属于该组的样本被聚类到别的组了,那就说明这个样本本身的变异度很高,或者说在之前的样本采集或者测序过程中出了什么问题。

5,行聚类,如果不聚类,排序将保持文件数据的默认方式。从基因表达角度讲,聚类可以观察到哪些基因群体具有比较一致的表达变化,因为基因的上下游关系一般是连锁反应的,也就是说一个基因的表达增加可能能够带动一系列的基因的表达增加。

6,列分组信息。

7,行分组信息。

绘图前的数据准备

热图数据

数据来源一般是搜库结果定量表。包含2个维度的数据,一般情况下,每一行是一个基因,每一列是一个样本。

demo数据可以在https://www.r2omics.cn/res/demodata/heatmap/data.heatmap.txt下载。

样本分组数据(可选)

行名的名称和个数要和之前的heatmap数据保持一致,列名为分组名称,可以包含不止一个分组。

demo数据可以在https://www.r2omics.cn/res/demodata/heatmap/sample.class.txt下载。

基因分组数据(可选)

行名的名称和个数要和之前的heatmap数据保持一致,列名为分组名称,可以包含不止一个分组。

demo数据可以在https://www.r2omics.cn/res/demodata/heatmap/gene.class.txt下载。

R语言怎么画热图

1. 数据读取与处理

  • 读取数据

  • 归一化

  • 转化为ggplot2格式的数据类型。长数据

# 代码来源:https://www.r2omics.cn/
library(tidyverse)
library(ggtree)  #聚类
library(aplot)   #拼图

# 读取数据
df = read.delim("https://www.r2omics.cn/res/demodata/heatmap/data.heatmap.txt",row.names = 1) 

# 归一化
# 按行归一化
dfNormalize = t(scale(t(df))) %>% as.data.frame()

# # (或)按列归一化
# dfNormalize = scale(df) %>% as.data.frame()

# 转化为ggplot2格式的数据类型。长数据
dfLong = dfNormalize %>%
  rownames_to_column("Gene") %>%
  pivot_longer(-1,names_to = "Sample",values_to = "Value")
dfLong
# A tibble: 300 x 3
   Gene  Sample   Value
   <chr> <chr>    <dbl>
 1 Gene1 Sample1  0.918
 2 Gene1 Sample2  1.37 
 3 Gene1 Sample3  0.172
 4 Gene1 Sample4 -0.530
 5 Gene1 Sample5 -0.719
 6 Gene1 Sample6 -1.21 
 7 Gene2 Sample1 -0.905
 8 Gene2 Sample2 -0.517
 9 Gene2 Sample3 -1.16 
10 Gene2 Sample4  0.372
# i 290 more rows

2. 基本绘图

# 基本绘图
p = ggplot(dfLong,aes(x=Sample,y=Gene,fill=Value))+
  geom_raster()+
  scale_fill_gradient2(low="#0000ff", high="#ff0000", mid="#ffffff")+
  scale_y_discrete(position="right") +
  theme_minimal()+
  theme(panel.grid.major=element_blank())
p

3. 添加分组条带

# 添加分组条带

# X轴(单条带例子)
dfSample = read.delim("https://www.bioladder.cn/shiny/zyp/demoData/heatmap/sample.class.txt")
pX = dfSample %>%
  mutate(Y = "Group") %>%
  ggplot(aes(x=X,y=Y,fill=Group))+
  geom_tile() +
  theme_void()+
  labs(fill = "Group")

# y轴(双条带例子)
dfGene = read.delim("https://www.bioladder.cn/shiny/zyp/demoData/heatmap/gene.class.txt")  
pY = dfGene %>%
  pivot_longer(-1) %>%
  ggplot(aes(x=name,y=X,fill=value))+
  geom_tile() +

  theme_void()+
  labs(fill = "Class")

# 拼图
p %>%
  insert_top(pX, height = .05)%>%
  insert_left(pY, width = .09)

4. 添加聚类树

# 聚类树
phY <- dfNormalize %>%
    dist(method = "euclidean")%>%
    hclust(method = "complete")%>%
    ggtree(layout="rectangular",branch.length="none")

phX <- dfNormalize %>%
  t()%>%
  dist(method = "euclidean")%>%
  hclust(method = "complete")%>%
  ggtree(layout="rectangular",branch.length="none")+
  layout_dendrogram()

p %>%
  insert_top(pX, height = .05) %>%
  insert_left(pY, width = .09) %>%
  insert_left(phY,width=.2) %>%
  insert_top(phX,height=.2)