关于heatmap

一、热图的介绍

(1)什么是热图

热图是heatmap的直译,用暖色表示数值大,冷色表示数值小。行为基因,列为样本。

(2)热图的作用

  • 数据质量控制:通过热图,我们能很直观的看到不同分组之间的基因整体表达模式,因此可以迅速地判断同组之间各样本的重复性如何,从而判断实验处理是否正确,数据是否可信可靠符合逻辑。相同实验分组的几个生物学重复应该聚类在一起。
  • 直观展示重点研究对象的表达量数据差异变化情况:一次实验中检测到的基因往往成千上万,导致一幅全局性热图的行数也相应地十分庞大,单个基因的表达情况几乎无法辨识,所以用整个数据集画出的热图往往只能用于数据的整体质控。而要能够向读者清晰展示自己所研究的某一批基因的数据分布与变化情况,就应当把自己的研究对象从数据集中找出来再绘制热图,作为重点关注的几个标志性的基因在右侧标注。
  • 不要画“没用”的热图,比如图形的展示结果是早可预见的,没用什么意义的热图;用于进行探索性数据分析、提供下游分析处理线索的热图。应该能够解释:这个热图展示的特定的表达模式,说明了哪些生物学功能与信号通路的改变?是什么导致了这些改变?这种改变又会产生什么样的后果?

二、热图中数据的标准化

(1)为什么要标准化

热图的图例是以0为中心,变化范围在±3左右。RNA-seq得到的基因表达量其实差异是非常大的,从个位数到上千,所以首先要对基因的表达量进行归一化,不然我们得需要多大尺度的色阶才能表示这么大范围的变化啊。标准化可以使数据范围缩小,便于用合适的颜色色度进行表示,能避免由于单个数据过大(过小),导致冷暖色分布不明显的现象。

(2)怎样标准化

可以按基因、按样本或全局标准化。一般选择按行(基因)进行标准化。如果对同一行进行标准化,就不能比较同一样品中不同基因的表达(不能比较不在同一行的z-score数值,原来不同基因绝对表达量高的也有可能在同一样品中得到低的z-score分数)。如果没有异常值,也可以进行全局的标准化。

(3)标准化方法

  • Z-score scaling(正态标准化):它代表原始数值和总体均值之间的距离,并以标准差为单位计算。在原始数值低于平均值时Z则为负数,反之则为正数,是一个不受原始测量单位影响的数值,经常用在数据分化比较大的场景。在分类、聚类、PCA算法中,使用z-score值的结果更好。转换后的数据符合正态分布,平均数为0,方差为1。Z-score要求原始数据的分布为正态分布或者近似正态分布。
    z-score = (x-μ)/SD
  • log对数变换:原始的counts矩阵是一个离散型的变量,离散程度很高。即使经过了RPKM/FPKM等方法抵消了一些测序技术误差的影响,但高低丰度基因的表达量的差距依然很大。常用的归一化方法是对数转换log2(counts+1)。加1是因为表达量为0的无法取到对数,而加1后log2(1)还是等于0。转换后不改变数据原本的排序关系,可以在全局进行比较。
  • min-max标准化(0-1标准化):是对原始数据的线性变换,使结果落到[0 , 1]区间。更符合直观认知,使同一行里基因表达最高值为1,最低值为0。

三、热图中数据的聚类

(1)什么是聚类

聚类,就是把相似的东西分到一组。一个聚类算法通常只需要知道如何计算相似度就可以开始工作了,是无监督学习。聚类本质上是集合划分问题。因为没有人工定义的类别标准,因此算法要解决的核心问题是如何定义簇,唯一的要求是簇内的样本尽可能相似。通常的做法是根据簇内样本之间的距离,或是样本点在数据空间中的密度来确定。对簇的不同定义可以得到各种不同的聚类算法。常见的聚类算法有:

  • 连通性聚类。典型代表是层次聚类算法,它根据样本之间的联通性来构造簇,所有联通的样本属于同一个簇。
  • 基于质心的聚类。典型代表是k均值算法,它用一个中心向量来表示这个簇,样本所属的簇由它到每个簇的中心距离确定。

(2)层次聚类

找出哪两个基因最相似(similar),将它们合并作为一个整体(merge them to a cluster);再找出哪两个基因最相似,合并成一个整体;重复这个步骤,直到所有的基因都聚成一类。
层次聚类通常会伴随着产生一个系统树图(dendrogram),表示了相似性和聚类的顺序。

(3)相似性如何定义

可以有多种计算距离的方式,如Euclidean distance(欧氏距离)、Manhattan distance等,现实中绝大多数时候会使用欧氏距离。使用包含欧氏距离的聚类算法时,要注意数据的量纲影响,有必要时先进行数据标准化处理。
You need to make sure the scales for each variable are roughly equivalent, otherwise you will be biased towards one of them. The standard practice is to divide each variable by its standard deviation.

(4)聚类如何作为一个整体

  • the average(类平均法):类与另一个类中任两个样品距离的平均值。效果比较好。
  • the closest point:single-linkage
  • the furthest point:complete-linkage
  • centroid(重心):类的均值与另一个类的均值的距离
  • median(中间距离法)
  • ward(离差平方和法)
  • density(密度估计法)

四、pheatmap(Pretty Heatmaps)

(1)R Script

> library(pheatmap) 
> library(RColorBrewer) 

> #测试数据
> testdata1[1:5,1:5]
              CF1      CF2      CF3      CF4       CM1
rna13468 66.97984 80.07318 54.87525 91.65463  1.401584
rna885   26.53467 44.51450 33.65076 40.72113 60.633389
rna32332  0.00000 37.71825 11.89813  0.00000  1.403419
rna8744  42.44415 52.31791 60.35968 54.00533 39.524090
rna16488  0.00000  0.00000  0.00000  0.00000  0.000000
> #样本信息
> anno_col <- data.frame(Group=c(rep("CF",4),rep("CM",4),
+                                rep("PF",4),rep("PM",4)), 
+                        row.names = colnames(testdata1)) 
> anno_col$Group <- factor(anno_col$Group,levels=unique(anno_col$Group))

> #基因注释
> head(anno_row)
         gene_name chromosome
rna10784   CG13244         2L
rna12885   CG14589         2R
rna13468    CG1882         2R
rna16488    CG8311         2R
rna18953    CG5539         2R
rna20313    CG1317         3L
> anno_row$chromosome <- droplevels(anno_row$chromosome)
> #注释颜色
> Group_col <- brewer.pal(8,"Set2")[2:5]
> names(Group_col) <- levels(anno_col$Group)
> Chr_col <- brewer.pal(8,"Set3")[1:5]
> names(Chr_col) <- levels(anno_row$chromosome)
> ann_colors <- list(Group=Group_col, 
+                    Chromosome=Chr_col)
> #默认参数绘图
> pheatmap(testdata1)
pheatmap-default.JPG
> #添加注释等
pheatmap( testdata1, 
+           scale="row", 
+           clustering_method="average", 
+           color=colorRampPalette(c("green", "black","red"))(100), 
+           annotation_col=anno_col, 
+           annotation_row=anno_row[2], 
+           annotation_names_row=F, annotation_names_col=T, 
+           annotation_colors=ann_colors, 
+           border_color = NA)
pheatmap-annotation.JPG

(2)用法

pheatmap(mat, color = colorRampPalette(rev(brewer.pal(n = 7, name = "RdYlBu")))(100), kmeans_k = NA, breaks = NA, border_color = "grey60", cellwidth = NA, cellheight = NA, scale = "none", cluster_rows = TRUE, cluster_cols = TRUE, clustering_distance_rows = "euclidean", clustering_distance_cols = "euclidean", clustering_method = "complete", clustering_callback = identity2, cutree_rows = NA, cutree_cols = NA, treeheight_row = ifelse((class(cluster_rows) == "hclust") || cluster_rows, 50, 0), treeheight_col = ifelse((class(cluster_cols) == "hclust") || cluster_cols, 50, 0), legend = TRUE, legend_breaks = NA, legend_labels = NA, annotation_row = NA, annotation_col = NA, annotation = NA, annotation_colors = NA, annotation_legend = TRUE, annotation_names_row = TRUE, annotation_names_col = TRUE, drop_levels = TRUE, show_rownames = T, show_colnames = T, main = NA, fontsize = 10, fontsize_row = fontsize, fontsize_col = fontsize, angle_col = c("270", "0", "45", "90", "315"), display_numbers = F, number_format = "%.2f", number_color = "grey30", fontsize_number = 0.8 * fontsize, gaps_row = NULL, gaps_col = NULL, labels_row = NULL, labels_col = NULL, filename = NA, width = NA, height = NA, silent = FALSE, na_col = "#DDDDDD", ...)

(3)参数

  • scale="row" #标准化z-score,按行(基因)row/按列column/不标准化none
  • cluster_rows=T, cluster_cols=T #默认聚类
  • clustering_distance_rows="euclidean", clustering_distance_cols="euclidean" #默认欧氏距离
  • clustering_method="complete" #默认最远距离
  • color=colorRampPalette(c("green", "black","red"))(100) #红黑绿
  • legend=TRUE, legend_breaks=NA, legend_labels=NA #默认图例
  • annotation_col=annotation_col, annotation_row=annotation_row, #行和列的注释
  • annotation_colors=ann_colors #设置分组颜色
  • annotation_legend=T #注释的图例
  • annotation_names_row=T, annotation_names_col=F #注释的名称
  • show_rownames=T, show_colnames=T #是否显示行名和列名
  • border_color = NA #方格边框颜色,默认"grey60" ,NA为不画边框
  • treeheight_row=30, treeheight_col=20 #进化树高度,设为0可隐藏进化树

五、ComplexHeatmap

(1)R Script

> library(ComplexHeatmap) 
> library(circlize) 
> library(RColorBrewer) 

> #提前标准化数据
> heatmapdata <- testdata1 
> heatmapdata <- t(scale(t(heatmapdata))) 
> #heatmapdata[heatmapdata>2]=2 
> #heatmapdata[heatmapdata<-2]=-2 

默认参数绘图

> Heatmap(testdata1)
> Heatmap(heatmapdata)

ComplexHeatmap-default.JPG

热图颜色

> col_fun = colorRamp2(c(-2, 0, 2), c("green", "white", "red"))
> Heatmap(heatmapdata, name=" ", col=col_fun)
> Heatmap(heatmapdata, name=" ", col=rev(rainbow(10)))

ComplexHeatmap-col.JPG

边界和网格

> Heatmap(heatmapdata, name=" ", col=col_fun,
+         border=TRUE,rect_gp=gpar(col="white",lwd=2))

ComplexHeatmap-border.JPG

渲染聚类树

> #install.packages("dendextend")
> library(dendextend)
> col_dend = hclust(dist(t(heatmapdata)))
> row_dend = hclust(dist(heatmapdata))
> Heatmap(heatmapdata, name=" ", 
+         cluster_columns=color_branches(col_dend,k=4),
+         cluster_rows = color_branches(row_dend, k=4))

ComplexHeatmap-dendextend.JPG

组内聚类

> Heatmap(heatmapdata, name=" ", 
+         cluster_columns=cluster_within_group(heatmapdata,anno_col$Group))

ComplexHeatmap-cluster_within_group.JPG

分割热图

> Heatmap(heatmapdata, name=" ", 
+         split = anno_row$chromosome,
+         column_split = anno_col$Group)
> Heatmap(heatmapdata, name=" ", 
+         split = anno_row$chromosome,
+         column_split = anno_col$Group,
+         column_title = NULL,
+         row_title_gp = gpar(col="white",fontsize=11,
+                             fill=brewer.pal(8,"Set1")[1:5]))

ComplexHeatmap-split.JPG

图例

> Heatmap(heatmapdata, name=" ",
+         heatmap_legend_param = list(legend_height=unit(6,"cm"),
+                                     grid_width=unit(0.8,"cm")))

ComplexHeatmap-legend.JPG

简单注释

> ha_col <- HeatmapAnnotation(Group=anno_col$Group,
+                         col=list(Group=Group_col))
> ha_row <- HeatmapAnnotation(Chr=anno_row$chromosome,
+                             col=list(Chr=Chr_col),
+                             which="row")
> Heatmap(heatmapdata, name=" ",
+         top_annotation = ha_col,
+         left_annotation = ha_row)

ComplexHeatmap-annotation.JPG

复杂注释

> ha_box <- HeatmapAnnotation(boxplot=anno_boxplot(heatmapdata,
+                                                  height=unit(2,"cm"),
+                                                  box_width = 0.9,
+                                                  gp=gpar(fill=Chr_col[anno_row$chromosome]),
+                                                  outline = F),
+                             which="row")
> Heatmap(heatmapdata, name=" ",
+         top_annotation = ha_col,
+         left_annotation = ha_row,
+         right_annotation = ha_box)

ComplexHeatmap-annotation-box.JPG

标签注释

> ha_lab <- rowAnnotation(gene=anno_mark(at=which(row.names(heatmapdata)=="rna34188"),
+                                        labels = "CycG"))
> Heatmap(heatmapdata, name=" ",
+         show_row_names = F,
+         right_annotation = ha_lab)
ComplexHeatmap-annotation-lab.JPG

(2)reference

可以去看ComplexHeatmap Complete Reference,非常详细。

single-heatmap.JPG

heatmap-list.JPG
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342