美文网首页R语言ComplexHeatmap复杂热图
ComplexHeatmap复杂热图绘制学习——3.热图注释(一

ComplexHeatmap复杂热图绘制学习——3.热图注释(一

作者: denghb001 | 来源:发表于2021-10-21 16:59 被阅读0次

    第 3 章 热图注释

    热图注释是热图的重要组成部分,它显示与热图中的行或列相关联的附加信息。 ComplexHeatmap包为设置注释和定义新的注释图形提供了非常灵活的支持。注释可以放在热图的四个侧面,由top_annotationbottom_annotationleft_annotationright_annotation参数组成。

    接下来我们将对不同第注释函数anno_*()进行说明,如空注释anno_empty()、块注释anno_block()、图像注释anno_image()、点注释anno_points()、线注释anno_lines()、条形图注释anno_barplot()、箱线图注释anno_boxplot()、直方图注释anno_histogram()、密度注释anno_density()等注释方法。

    四个参数的值应该在HeatmapAnnotation类中并且由HeatmapAnnotation()函数构造,如果是行注释则由rowAnnotation()函数构造。(rowAnnotation()只是一个与HeatmapAnnotation(..., which = "row")相同的辅助函数) ,热图注释的简单用法如下。

    set.seed(123)
    mat = matrix(rnorm(100), 10)
    rownames(mat) = paste0("R", 1:10)
    colnames(mat) = paste0("C", 1:10)
    column_ha = HeatmapAnnotation(foo1 = runif(10), bar1 = anno_barplot(runif(10)))
    row_ha = rowAnnotation(foo2 = runif(10), bar2 = anno_barplot(runif(10)))
    Heatmap(mat, name = "mat", top_annotation = column_ha, right_annotation = row_ha)
    
    image

    将热图注释指定为底部注释和左侧注释。

    Heatmap(mat, name = "mat", bottom_annotation = column_ha, left_annotation = row_ha)
    
    image.png

    在上面的例子中,column_harow_ha都有两个注释,其中 foo1foo2是数字向量,bar1bar2是条形图。类似向量的注解在这里称为“简单注释”,条形图注解称为“复杂注释”。您已经可以看到注释必须定义为名称=值对(例如 foo = ...)。

    热图注释也可以独立于热图。它们可以通过+(水平连接)或%v%(垂直连接)到热图列表。

    # code only for demonstration
    Heatmap(...) + rowAnnotation() + ...
    Heatmap(...) %v% HeatmapAnnotation(...) + ...
    

    HeatmapAnnotation()返回一个HeatmapAnnotation类对象。对象通常由几个注释组成。如以下部分,首先介绍单个注释的设置,然后展示如何将它们组合在一起。

    可以看到column_harow_ha对象的信息:

    column_ha
    
    ## A HeatmapAnnotation object with 2 annotations
    ##   name: heatmap_annotation_0 
    ##   position: column 
    ##   items: 10 
    ##   width: 1npc 
    ##   height: 15.3514598035146mm 
    ##   this object is subsetable
    ##   5.92288888888889mm extension on the left 
    ##   9.4709mm extension on the right 
    ## 
    ##  name   annotation_type color_mapping height
    ##  foo1 continuous vector        random    5mm
    ##  bar1    anno_barplot()                 10mm
    
    row_ha
    
    ## A HeatmapAnnotation object with 2 annotations
    ##   name: heatmap_annotation_1 
    ##   position: row 
    ##   items: 10 
    ##   width: 15.3514598035146mm 
    ##   height: 1npc 
    ##   this object is subsetable
    ##   9.96242222222222mm extension on the bottom 
    ## 
    ##  name   annotation_type color_mapping width
    ##  foo2 continuous vector        random   5mm
    ##  bar2    anno_barplot()                10mm
    

    在本章的以下示例中,除非必要,否则我们将仅显示没有热图的注释图形。如果你想用一个热图来试试吧,你只需指定HeatmapAnnotation,我们是以ha名称来作为top_annotationbottom_annotationleft_annotationright_annotation讨论对象。

    列注释和行注释的设置基本相同。如果没有什么特别的,我们只以列注释作为示例。如果您想尝试一行注释,只需添加which = "row"HeatmapAnnotation()或直接切换到rowAnnotation()功能。

    3.1简单注释

    所谓的“简单注释”是最常用的注释样式,它是类似热图或类似网格的图形,其中使用颜色映射到注释值。要生成一个简单的注释,您只需简单地将一个特定的名称注释向量放入HeatmapAnnotation()中。

    ha = HeatmapAnnotation(foo = 1:10)
    
    image

    离散型数据注释:

    ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE))
    
    image

    除了HeatmapAnnotation(),您可以使用任何字符串作为注释名称。

    如果未指定颜色,则随机生成颜色。col设置注释的颜色,col需要设置命名列表。

    对于连续值注释,颜色映射应该是由 circlize::colorRamp2()生成的颜色映射函数。

    library(circlize)
    col_fun = colorRamp2(c(0, 5, 10), c("blue", "white", "red"))
    ha = HeatmapAnnotation(foo = 1:10, col = list(foo = col_fun))
    
    image

    对于离散注释,颜色应该是命名向量,其中名称对应于注释中的级别。

    ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE),
        col = list(bar = c("a" = "red", "b" = "green", "c" = "blue")))
    
    image

    如果您指定多个向量,则会有多个注释(foobar)。您还可以看到foobar全部放入单个HeatmapAnnotation()中是如何设置col . 也许现在您可以理解颜色列表中的名称实际上是用来映射到注释名称的。col中的值将用于构建简单注释的图例。

    ha = HeatmapAnnotation(
        foo = 1:10, 
        bar = sample(letters[1:3], 10, replace = TRUE),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        )
    )
    
    image

    NA值的颜色由na_col参数控制。

    ha = HeatmapAnnotation(
        foo = c(1:4, NA, 6:10), 
        bar = c(NA, sample(letters[1:3], 9, replace = TRUE)),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        ),
        na_col = "black"
    )
    
    image

    gp 主要控制网格边界的图形参数。

    ha = HeatmapAnnotation(
        foo = 1:10, 
        bar = sample(letters[1:3], 10, replace = TRUE),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        ),
        gp = gpar(col = "black")
    )
    
    image

    简单注释也可以是矩阵(数字或字符),矩阵中的所有列共享相同的颜色映射模式。注意矩阵中的列对应于列注释中的行。矩阵的列名称也用作注释名称。

    ha = HeatmapAnnotation(foo = cbind(a = runif(10), b = runif(10)))
    
    image.png

    如果矩阵没有列名,则仍然使用注解的名称,但绘制在注解的中间。

    ha = HeatmapAnnotation(foo = cbind(runif(10), runif(10)))
    
    image.png

    由于简单的注释可以采用不同的模式(例如数字或字符),它们可以组合为数据帧并发送到df参数。在你的项目中成像,你可能已经有了一个注释表,你可以直接通过 df.

    anno_df = data.frame(foo = 1:10,
        bar = sample(letters[1:3], 10, replace = TRUE))
    ha = HeatmapAnnotation(df = anno_df,
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        )
    )
    
    image.png

    单个注释和数据框可以混合使用。在以下示例中,foo2由于未指定颜色,将使用随机颜色。

    ha = HeatmapAnnotation(df = anno_df,
        foo2 = rnorm(10),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        )
    )
    
    image

    border 控制每个注释的边界。

    ha = HeatmapAnnotation(
        foo = cbind(1:10, 10:1),
        bar = sample(letters[1:3], 10, replace = TRUE),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        ),
        border = TRUE
    )
    
    image

    简单注释的高度由simple_anno_size 参数控制。由于所有单个注释具有相同的高度,因此 的值 simple_anno_size是单个unit值。注意有喜欢争论 widthheightannotation_widthannotation_height,但它们是用来调整的完整heamtap注释(这总是混合几种注释)的宽度/高度。

    ha = HeatmapAnnotation(
        foo = cbind(a = 1:10, b = 10:1), 
        bar = sample(letters[1:3], 10, replace = TRUE),
        col = list(foo = col_fun,
                   bar = c("a" = "red", "b" = "green", "c" = "blue")
        ),
        simple_anno_size = unit(1, "cm")
    )
    
    image

    当您有多个热图时,最好将所有热图上的简单注释的大小保持相同的大小。ht_opt$simple_anno_size可以设置全局控制简单注解的大小。

    3.2简单注释作为注释函数

    HeatmapAnnotation()通过将注释设置为函数来支持“复杂注释”。annotation 函数定义了如何在热图中的列或行对应的某个位置绘制图形。ComplexHeatmap包中预定义了很多注释函数 。在本章的最后,我们将介绍如何通过AnnotationFunction类构造自己的注释函数。

    对于anno_*()形式的所有注释函数,如果在HeatmapAnnotation()rowAnnotation()中指定 ,则不需要明确地做任何anno_*()事情来判断它是应该绘制在行上还是列上。anno_*()将会自动检测是行注释环境还是列注释环境。

    上一节中的简单注解是由anno_simple()注解函数内部构造的 。直接使用anno_simple() 不会自动为最终绘图生成图例,但是,它可以为更多的注释图形提供更大的灵活性(注意在第5章 我们将展示,虽然anno_simple()不能自动生成图例,但可以控制图例并添加到最终绘图中手动)。

    对于上一节中的示例:

    # code only for demonstration
    ha = HeatmapAnnotation(foo = 1:10)
    

    实际上等同于:

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_simple(1:10))
    

    anno_simple()制作类似热图的注释(或简单的注释)。基本上如果用户只做类似热图的注释,他们不需要直接使用anno_simple(),但是这个功能允许在注释网格上添加更多符号。

    anno_simple()允许在注释网格顶部添加“点”或单字母符号。pchpt_gppt_size控制点的设置。pch的值可以是具有可能NA值的向量。

    ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1, 
        pt_gp = gpar(col = "red"), pt_size = unit(1:10, "mm")))
    
    image

    设置pch为向量:

    ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1:10))
    
    image

    设置pch为字母向量:

    ha = HeatmapAnnotation(foo = anno_simple(1:10, 
        pch = sample(letters[1:3], 10, replace = TRUE)))
    
    image

    设置pch为带有NA值的向量(pch 值为NA不绘制任何内容):

    ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = c(1:4, NA, 6:8, NA, 10, 11)))
    
    image

    如果 anno_simple()的值是矩阵,pch也可以使用。 pch的长度应该与矩阵的行数或列数甚至矩阵的长度相同(矩阵的长度是矩阵中所有数据点的长度)。

    pch的长度对应矩阵的列:

    ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:2))
    
    image

    pch对应于矩阵行的长度:

    ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:10))
    
    image.png

    pch 是一个矩阵:

    pch = matrix(1:20, nc = 2)
    pch[sample(length(pch), 10)] = NA
    ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = pch))
    
    image

    到现在为止,您可能想知道如何设置已添加到简单注释中的符号的图例。在这里,我们将仅向您展示一个简单的示例,在下面的例子中,我们假设简单的注释是一种 p 值,我们将 p 值小于 0.01 的添加*

    set.seed(123)
    pvalue = 10^-runif(10, min = 0, max = 3)
    is_sig = pvalue < 0.01
    pch = rep("*", 10)
    pch[!is_sig] = NA
    # color mapping for -log10(pvalue)
    pvalue_col_fun = colorRamp2(c(0, 2, 3), c("green", "white", "red")) 
    ha = HeatmapAnnotation(
        pvalue = anno_simple(-log10(pvalue), col = pvalue_col_fun, pch = pch),
        annotation_name_side = "left")
    ht = Heatmap(matrix(rnorm(100), 10), name = "mat", top_annotation = ha)
    # now we generate two legends, one for the p-value
    # see how we define the legend for pvalue
    lgd_pvalue = Legend(title = "p-value", col_fun = pvalue_col_fun, at = c(0, 1, 2, 3), 
        labels = c("1", "0.1", "0.01", "0.001"))
    # and one for the significant p-values
    lgd_sig = Legend(pch = "*", type = "points", labels = "< 0.01")
    # these two self-defined legends are added to the plot by `annotation_legend_list`
    draw(ht, annotation_legend_list = list(lgd_pvalue, lgd_sig))
    
    image

    anno_simple()的高度可以通过height参数或 simple_anno_size内部控制。simple_anno_size控制单行注释的大小和height/width控制简单注释的总高度/宽度。如果设置了height/ widthsimple_anno_size则被忽略。

    ha = HeatmapAnnotation(foo = anno_simple(1:10, height = unit(2, "cm")))
    
    image
    ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), 
        simple_anno_size = unit(2, "cm")))
    
    image

    对于我们后面介绍的所有注释函数,单个注释的高度或宽度都应该在anno_*() 函数内部进行设置。

    # code only for demonstration
    anno_*(..., width = ...)
    anno_*(..., height = ...)
    

    同样,widthheightannotation_widthannotation_height 在参数HeatmapAnnotation()被用于调整多个注释的大小。

    3.3 空注释

    anno_empty()是一个不绘制任何内容的占位符。以后可以通过decorate_annotation()功能添加用户定义的图形。

    ha = HeatmapAnnotation(foo = anno_empty(border = TRUE))
    
    image

    在后续章节中将介绍装饰函数的使用,但在这里我们举一个简单的例子。在基因表达表达分析中,有些情况下我们将热图分成几组,我们希望突出显示每组中的一些关键基因。在这种情况下,我们只需将基因名称添加到热图的右侧,而不将它们与相应的行对齐。(anno_mark()可以将标签正确地与其对应的行对齐,但在在这里显示的示例中,这不是必需的)。

    在以下示例中,由于行被拆分为四个切片,因此空注释也被拆分为四个切片。基本上我们所做的是在每个空的注释切片中,我们添加一个彩色段和文本。

    random_text = function(n) {
        sapply(1:n, function(i) {
            paste0(sample(letters, sample(4:10, 1)), collapse = "")
        })
    }
    text_list = list(
        text1 = random_text(4),
        text2 = random_text(4),
        text3 = random_text(4),
        text4 = random_text(4)
    )
    # note how we set the width of this empty annotation
    ha = rowAnnotation(foo = anno_empty(border = FALSE, 
        width = max_text_width(unlist(text_list)) + unit(4, "mm")))
    Heatmap(matrix(rnorm(1000), nrow = 100), name = "mat", row_km = 4, right_annotation = ha)
    for(i in 1:4) {
        decorate_annotation("foo", slice = i, {
            grid.rect(x = 0, width = unit(2, "mm"), gp = gpar(fill = i, col = NA), just = "left")
            grid.text(paste(text_list[[i]], collapse = "\n"), x = unit(4, "mm"), just = "left")
        })
    }
    
    image

    空注释的第二个用途是添加复杂的注释图形,其中空注释伪装成虚拟绘图区域。可以AnnotationFunction为复杂的注释图形按类构造注释函数,允许子集和拆分,但仍然可以作为次要选择,直接在空注释内部绘制,实现起来更容易、更快(但灵活性较差,不允许拆分)。

    下面我们将展示如何添加点注释的“复杂版本”。唯一需要注意的是x轴(y轴如果是行注释)上的位置应该对应列重新排序后的列索引。

    ha = HeatmapAnnotation(foo = anno_empty(border = TRUE, height = unit(3, "cm")))
    ht = Heatmap(matrix(rnorm(100), nrow = 10), name = "mat", top_annotation = ha)
    ht = draw(ht)
    co = column_order(ht)
    value = runif(10)
    decorate_annotation("foo", {
        # value on x-axis is always 1:ncol(mat)
        x = 1:10
        # while values on y-axis is the value after column reordering
        value = value[co]
        pushViewport(viewport(xscale = c(0.5, 10.5), yscale = c(0, 1)))
        grid.lines(c(0.5, 10.5), c(0.5, 0.5), gp = gpar(lty = 2),
            default.units = "native")
        grid.points(x, value, pch = 16, size = unit(2, "mm"),
            gp = gpar(col = ifelse(value > 0.5, "red", "blue")), default.units = "native")
        grid.yaxis(at = c(0, 0.5, 1))
        popViewport()
    })
    
    image

    3.4块注释

    块注释更像是一个颜色块,它在热图的行或列被拆分时标识组。

    Heatmap(matrix(rnorm(100), 10), name = "mat",
        top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4))),
        column_km = 3)
    
    image

    标签可以添加到每个块。

    Heatmap(matrix(rnorm(100), 10), 
        top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
            labels = c("group1", "group2", "group3"), 
            labels_gp = gpar(col = "white", fontsize = 10))),
        column_km = 3,
        left_annotation = rowAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
            labels = c("group1", "group2", "group3"), 
            labels_gp = gpar(col = "white", fontsize = 10))),
        row_km = 3)
    
    image

    请注意,labels或图形参数的长度应与切片数具有相同的长度。

    anno_block()函数为行/列切片绘制矩形,其中一个矩形仅对应一个切片。那么,如果我们想在多个切片上绘制矩形以显示它们属于某些组,该怎么办,如下面的热图所示?

    set.seed(123)
    mat2 = matrix(rnorm(50*50), nrow = 50)
    ha = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5]))
    split = rep(1:5, each = 10)
    Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha, 
        column_title = NULL)
    
    image

    目前,很难在anno_block()中直接支持它,但仍然有解决方法。实际上,要在多个切片上绘制矩形,我们需要知道两件事:1. 切片在图中的位置 2. 绘制矩形的空间。庆幸的是位置可以通过直接转到对应的视窗获得,并且可以通过anno_empty()函数分配空间。

    在下面的代码中,我们使用anno_empty()创建一个空注释:

    ha = HeatmapAnnotation(
        empty = anno_empty(border = FALSE),
        foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
    )
    Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha, 
        column_title = NULL)
    
    image

    假设我们要将前三列切片作为一组,将后两列切片作为第二组。

    用于注释的第一和第三切片的位置"empty"可以通过以下方式获得:

    seekViewport("annotation_empty_1")
    loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
    seekViewport("annotation_empty_3")
    loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
    loc2
    
    ## $x
    ## [1] 4.07403126835173inches
    ## 
    ## $y
    ## [1] 6.51051067246731inches
    

    视图窗口名称"annotation_empty_1"对应于注释的第一个切片empty,我们取第一个“空”注释切片的左下角和第三个切片的右上角,保存在loc1loc2变量中。

    这里重要的是grid::deviceLoc()函数的使用。它直接将在某个视口中测量的位置转换为图形设备中的位置。

    最后,我们去"global"视口,因为"global" 视口的大小是图形设备的大小,绘制矩形并添加标签。

    seekViewport("global")
    grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y, 
        just = c("left", "bottom"), gp = gpar(fill = "red"))
    grid.text("group 1", x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5)
    
    image

    注释的视图窗口名称采用固定格式,即 annotation_{annotation_name}_{slice_index}. 可以通过list_components()函数获取完整的视口名称集。

    list_components()
    
    ##  [1] "ROOT"                        "global"                     
    ##  [3] "global_layout"               "global-heatmaplist"         
    ##  [5] "main_heatmap_list"           "heatmap_mat2"               
    ##  [7] "mat2_heatmap_body_wrap"      "mat2_heatmap_body_1_1"      
    ##  [9] "mat2_heatmap_body_1_2"       "mat2_heatmap_body_1_3"      
    ## [11] "mat2_heatmap_body_1_4"       "mat2_heatmap_body_1_5"      
    ## [13] "mat2_dend_row_1"             "mat2_dend_column_1"         
    ## [15] "mat2_dend_column_2"          "mat2_dend_column_3"         
    ## [17] "mat2_dend_column_4"          "mat2_dend_column_5"         
    ## [19] "annotation_empty_1"          "annotation_foo_1"           
    ## [21] "annotation_empty_2"          "annotation_foo_2"           
    ## [23] "annotation_empty_3"          "annotation_foo_3"           
    ## [25] "annotation_empty_4"          "annotation_foo_4"           
    ## [27] "annotation_empty_5"          "annotation_foo_5"           
    ## [29] "global-heatmap_legend_right" "heatmap_legend"
    

    如果要添加多个组级矩形,我们可以将代码包装成一个简单的函数group_block_anno()

    ha = HeatmapAnnotation(
        empty = anno_empty(border = FALSE, height = unit(8, "mm")),
        foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
    )
    Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha, 
        column_title = NULL)
    
    library(GetoptLong)  # for the function qq()
    group_block_anno = function(group, empty_anno, gp = gpar(), 
        label = NULL, label_gp = gpar()) {
    
        seekViewport(qq("annotation_@{empty_anno}_@{min(group)}"))
        loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
        seekViewport(qq("annotation_@{empty_anno}_@{max(group)}"))
        loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
    
        seekViewport("global")
        grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y, 
            just = c("left", "bottom"), gp = gp)
        if(!is.null(label)) {
            grid.text(label, x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5, gp = label_gp)
        }
    }
    
    group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
    group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
    
    image

    当热图被分割时,块注释中的每个块都可以被认为是一个虚拟的绘图区域。anno_block()允许一个新参数graphics,该参数接受在每个切片中绘制图形的自定义函数。它必须有两个参数:

    1. 当前切片的行/列索引(我们称之为index),
    2. 来自 split 变量的与当前切片相对应的水平向量(我们称之为level)。当 e.g row_km仅设置或row_split仅设置为一个分类变量时,则level是长度为 1 的向量。如果有多个分类变量用row_km和设置row_splitlevel则是一个长度与分类变量个数相同的向量。

    设置图形时,将忽略 anno_block 中的所有其他图形参数。请参阅以下示例:

    col = c("1" = "red", "2" = "blue", "A" = "green", "B" = "orange")
    Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) + 
    rowAnnotation(foo = anno_block(
        graphics = function(index, levels) {
            grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
            txt = paste(levels, collapse = ",")
            txt = paste0(txt, "\n", length(index), " rows")
            grid.text(txt, 0.5, 0.5, rot = 0,
                gp = gpar(col = col[levels[1]]))
        },
        width = unit(3, "cm")
    ))
    
    image

    3.5图像标注

    图像可以作为注释。anno_image()支持png, svg, pdf, eps, jpeg/jpg,tiff格式的图像。它们作为注释导入的方式如下:

    • pngjpeg/jpgtiff图像由png::readPNG()jpeg::readJPEG()tiff::readTIFF()导入并由 grid::grid.raster()绘制。
    • svg图像首先由rsvg::rsvg_svg()重新格式化,然后由grImport2::readPicture()导入和grImport2::grid.picture()绘制。
    • pdfeps图像由grImport::PostScriptTrace()grImport::readPicture()导入,然后由 grImport::grid.picture()绘制。

    以下示例的免费图标来自 https://github.com/Keyamoon/IcoMoon-Free。图像路径向量被设置为 的第一个参数anno_image()

    image_png = sample(dir("IcoMoon-Free-master/PNG/64px", full.names = TRUE), 10)
    image_svg = sample(dir("IcoMoon-Free-master/SVG/", full.names = TRUE), 10)
    image_eps = sample(dir("IcoMoon-Free-master/EPS/", full.names = TRUE), 10)
    image_pdf = sample(dir("IcoMoon-Free-master/PDF/", full.names = TRUE), 10)
    
    # we only draw the image annotation for PNG images, while the others are the same
    ha = HeatmapAnnotation(foo = anno_image(image_png))
    
    image

    不同格式的图像可以在输入向量中混合使用。

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_image(c(image_png[1:3], image_svg[1:3], 
        image_eps[1:3], image_pdf[1:3])))
    

    边框和背景颜色(如果图像具有透明背景)可以通过gp设置。

    ha = HeatmapAnnotation(foo = anno_image(image_png, 
        gp = gpar(fill = 1:10, col = "black")))
    
    image

    border 控制整个边界的注释。

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_image(image_png, border = "red"))
    

    图像周围的填充或空间由 space设置。

    ha = HeatmapAnnotation(foo = anno_image(image_png, space = unit(3, "mm")))
    
    image

    如果只需要绘制部分图像,可以将image 向量中的其它元素设置为''NA

    image_png[1:2] = ""
    ha = HeatmapAnnotation(foo = anno_image(image_png))
    
    image

    3.6 点注释

    点注释anno_points()为实现显示数据点在列表中的分布。数据点对象x可以是单个向量或矩阵。如果它是一个矩阵,图形属性设置(例如pchsizegp)可以关联到矩阵的列。再次注意,如果x是矩阵,则行x 对应于热图矩阵中的列。

    ha = HeatmapAnnotation(foo = anno_points(runif(10)))
    
    image
    ha = HeatmapAnnotation(foo = anno_points(matrix(runif(20), nc = 2), 
        pch = 1:2, gp = gpar(col = 2:3)))
    
    image

    ylim控制“y轴”或“数据轴”上的范围(如果是行注释,则数据轴为水平),extend控制数据轴方向上的扩展空间。axis控制是否显示轴并控制轴 axis_param的设置。轴的默认设置为:

    default_axis_param("column")
    
    ## $at
    ## NULL
    ## 
    ## $labels
    ## NULL
    ## 
    ## $labels_rot
    ## [1] 0
    ## 
    ## $gp
    ## $fontsize
    ## [1] 8
    ## 
    ## 
    ## $side
    ## [1] "left"
    ## 
    ## $facing
    ## [1] "outside"
    ## 
    ## $direction
    ## [1] "normal"
    

    你可以覆盖其中的一些:

    ha = HeatmapAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
        axis_param = list(
            side = "right",
            at = c(0, 0.5, 1), 
            labels = c("zero", "half", "one")
        ))
    )
    
    image

    控制轴标签的旋转可能对你有用。

    ha = rowAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
        width = unit(2, "cm"),
        axis_param = list(
            side = "bottom",
            at = c(0, 0.5, 1), 
            labels = c("zero", "half", "one"),
            labels_rot = 45
        ))
    )
    
    image

    轴的配置与其他具有轴的注释功能相同。

    点注释的默认大小为 5mm。它可以由height/width中的参数控制 anno_points()

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_points(runif(10), height = unit(2, "cm")))
    

    3.7 线注释

    anno_lines()通过段列表连接数据点。与 anno_points()类似,数据变量可以是数值向量:

    ha = HeatmapAnnotation(foo = anno_lines(runif(10)))
    
    image

    或矩阵:

    ha = HeatmapAnnotation(foo = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)), 
        gp = gpar(col = 2:3), add_points = TRUE, pt_gp = gpar(col = 5:6), pch = c(1, 16)))
    
    image

    如上所示,可以通过设置将点添加到线中add_points = TRUE

    通过设置smooth = TRUE可以添加平滑线(by loess())而不是原始线,但应谨慎使用,因为热图中列的顺序用作拟合的“x值”,并且仅当您认为拟合反对重新排序的顺序是有道理的。

    当输入数据变量是对每一列单独执行平滑的矩阵时,平滑也有效。

    如果smoothTRUEadd_points则默认设置为TRUE

    ha = HeatmapAnnotation(foo = anno_lines(runif(10), smooth = TRUE))
    
    image

    线注释的默认大小为 5 毫米。它可以由height/ 中的width参数控制 anno_lines()

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_lines(runif(10), height = unit(2, "cm")))
    

    3.8条形图标注

    数据点可以表示为条形图。 anno_barplot()的一些参数:如ylimaxisaxis_paramanno_points()是一样的。

    ha = HeatmapAnnotation(foo = anno_barplot(1:10))
    
    image

    条行图的宽度由 bar_width控制。它是热图中单元格宽度的相对值。

    ha = HeatmapAnnotation(foo = anno_barplot(1:10, bar_width = 1))
    
    image

    图形参数由gp控制。

    ha = HeatmapAnnotation(foo = anno_barplot(1:10, gp = gpar(fill = 1:10)))
    
    image

    您可以通过baseline选择条形的基线。

    ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = "min"))
    
    image
    ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = 0))
    
    image

    如果输入值是一个矩阵,它将是堆叠的条形图。

    ha = HeatmapAnnotation(foo = anno_barplot(matrix(nc = 2, c(1:10, 10:1))))
    
    image

    gp参数的长度可以是矩阵中的列数:

    ha = HeatmapAnnotation(foo = anno_barplot(cbind(1:10, 10:1), 
        gp = gpar(fill = 2:3, col = 2:3)))
    
    image

    条形图注释的默认大小为 5 毫米。它可以由height/width中的参数控制 anno_barplot()

    # code only for demonstration
    ha = HeatmapAnnotation(foo = anno_barplot(runif(10), height = unit(2, "cm")))
    

    以下示例显示了可视化比例矩阵的条形图注释(行总和为 1)。

    m = matrix(runif(4*10), nc = 4)
    m = t(apply(m, 1, function(x) x/sum(x)))
    ha = HeatmapAnnotation(foo = anno_barplot(m, gp = gpar(fill = 2:5), 
        bar_width = 1, height = unit(6, "cm")))
    
    image

    轴的方向可以反转,这在注释放在热图左侧时很有用。

    ha_list = rowAnnotation(axis_reverse = anno_barplot(m, gp = gpar(fill = 2:5), 
        axis_param = list(direction = "reverse"), 
        bar_width = 1, width = unit(4, "cm"))) +
    rowAnnotation(axis_normal = anno_barplot(m, gp = gpar(fill = 2:5), 
        bar_width = 1, width = unit(4, "cm")))
    draw(ha_list, ht_gap = unit(4, "mm"))
    
    image

    direction = "reverse" 也适用于其他具有轴的注释函数,但它常用于条形图注释。

    add_numbers可以将参数设置为TRUE,以便在条形顶部绘制与条形关联的数字。对于列注释,文本默认旋转 45 度。

    ha = HeatmapAnnotation(foo = anno_barplot(1:10, add_numbers = TRUE, 
        height = unit(1, "cm")))
    
    image

    3.9箱线图注释

    Boxplot注解以及后面介绍的注解函数更适合小矩阵。不适合就有多列矩阵的列注释。

    对于anno_boxplot(),输入数据变量应该是矩阵或列表。如果 x是矩阵,如果是列注释,则箱线图的统计量按列计算,如果是行注释,则按行计算。

    set.seed(12345)
    m = matrix(rnorm(100), 10)
    ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm")))
    
    image

    图形参数由gp控制。

    ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"), 
        gp = gpar(fill = 1:10)))
    
    image

    框的宽度由box_width控制。outline控制是否显示离群点。

    ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"), 
        box_width = 0.9, outline = FALSE))
    
    image

    anno_boxplot()只为一行绘制一个箱线图。多个箱线图注释演示了如何定义为单行绘制多个箱线图的注释函数,单个箱线图演示如何为一组行绘制单个箱线图。

    3.10直方图标注

    作为直方图的注释更适合作为行注释。数据变量的设置与anno_boxplot()相同,可以是矩阵或列表。

    anno_boxplot()类似,输入数据变量应该是矩阵或列表。如果 x是矩阵,如果是列注释,则直方图按列计算,如果是行注释,则直方图按行计算。

    m = matrix(rnorm(1000), nc = 100)
    ha = rowAnnotation(foo = anno_histogram(m)) # apply `m` on rows
    
    image

    直方图的中断次数由n_breaks控制。

    ha = rowAnnotation(foo = anno_histogram(m, n_breaks = 20))
    
    image

    颜色由gp控制。

    ha = rowAnnotation(foo = anno_histogram(m, gp = gpar(fill = 1:10)))
    
    image

    3.11密度曲线注释

    与直方图注释类似,anno_density()将分布显示为拟合曲线。

    ha = rowAnnotation(foo = anno_density(m))
    
    image

    可以控制密度峰值的高度,使分布看起来像一个“joyplot”

    ha = rowAnnotation(foo = anno_density(m, joyplot_scale = 2, 
        gp = gpar(fill = "#CCCCCC80")))
    
    image

    或者将分布可视化为小提琴图。

    ha = rowAnnotation(foo = anno_density(m, type = "violin", 
        gp = gpar(fill = 1:10)))
    
    image

    当输入变量中有太多行时,正常密度峰值的空间可能太小。在这种情况下,我们可以通过热图可视化分布。

    m2 = matrix(rnorm(50*10), nrow = 50)
    ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm")))
    
    image

    热图分布的颜色模式由heatmap_colors控制。

    ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm"), 
        heatmap_colors = c("white", "orange")))
    
    image

    ComplexHeatmap包中,有一个densityHeatmap()函数可以将分布可视化为热图。将在密度热图介绍 。

    3.12 Joyplot注释

    anno_joyplot()特定于所谓的 Joyplot ( http://blog.revolutionanalytics.com/2017/07/joyplots.html )。输入数据应该是矩阵或列表。

    anno_joyplot()如果输入是矩阵,则注释始终应用于列。因为joyplot可视化了平行分布,矩阵不是必需的格式,列表已经足够了,如果你不确定如何设置为矩阵,只需将其转换为列表来使用它。

    m = matrix(rnorm(1000), nc = 10)
    lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
    ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"), 
        gp = gpar(fill = 1:10), transparency = 0.75))
    
    image

    或者只显示线条(scale参数控制曲线的相对高度)。

    m = matrix(rnorm(5000), nc = 50)
    lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
    ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"), gp = gpar(fill = NA), 
        scale = 4))
    
    image

    输入变量的格式很特殊。它可以是以下两个之一:

    1. 一个矩阵(记住anno_joyplot()总是应用于矩阵的列),其中 x 坐标1:nrow(matrix)对应于矩阵中的每一列对应于图中的一个分布。
    2. 一个数据框列表,其中每个数据框有两列对应于 x 坐标和 y 坐标。

    3.13地平线图标注

    水平线图 作为注释只能添加为行注释。输入变量的格式与上面介绍anno_horizon()的相同anno_joyplot()

    地平线图注释的默认样式为:

    lt = lapply(1:20, function(x) cumprod(1 + runif(1000, -x/100, x/100)) - 1)
    ha = rowAnnotation(foo = anno_horizon(lt))
    
    image

    每个轨道中的值通过 归一化x/max(abs(x))

    对于正值和负值的颜色是由gpar()pos_fillneg_fill控制。

    ha = rowAnnotation(foo = anno_horizon(lt, 
        gp = gpar(pos_fill = "orange", neg_fill = "darkgreen")))
    
    image

    pos_fillneg_fill可以作为向量分配。

    ha = rowAnnotation(foo = anno_horizon(lt, 
        gp = gpar(pos_fill = rep(c("orange", "red"), each = 10),
                  neg_fill = rep(c("darkgreen", "blue"), each = 10))))
    
    image

    负值的峰值是从底部还是从顶部开始。

    ha = rowAnnotation(foo = anno_horizon(lt, negative_from_top = TRUE))
    
    image

    每两个相邻图表之间的空间。

    ha = rowAnnotation(foo = anno_horizon(lt, gap = unit(1, "mm")))
    
    image

    相关文章

      网友评论

        本文标题:ComplexHeatmap复杂热图绘制学习——3.热图注释(一

        本文链接:https://www.haomeiwen.com/subject/ycutaltx.html