Pretty and Parallel Heatmap

Author: Zuguang Gu ( z.gu@dkfz.de )

Data: r Sys.Date()


library(knitr)
knitr::opts_chunk$set(
    error = FALSE,
    tidy  = FALSE,
    message = FALSE,
    fig.align = "center")
options(markdown.HTML.stylesheet = "custom.css")

pheatmap2 package is based on original pheatmap package. It uses almost same syntax as pheatmap but removes arguments which are not commonly used. It now supports adding more than one heatmap on the plot.

First, let's generate a matrix.

set.seed(123)
mat = rbind(matrix(rnorm(50, 1), 5, ),
            matrix(rnorm(50, -1), 5))
colnames(mat) = paste0("c", 1:10)
rownames(mat) = paste0("r", 1:10)

Plot the matrix with default setting:

library(pheatmap2)
pheatmap2(mat)

With some basic settings:

pheatmap2(mat, cluster_rows = FALSE, cluster_cols = FALSE, 
    show_colnames = FALSE, show_rownames = FALSE, legend_title = NULL)

pheatmap2 uses a function to map values to colors. circlize provides such a generator function which generates a color mapping function based on breaks values and corresponding colors. In following example, values less than -3 will be mapped to full green, it will be mapped between green and white linearly if the value is between -3 and 0.

library(circlize)
pheatmap2(mat, col_fun = colorRamp2(c(-3, 0, 3), c("green", "white", "red")))

One of the advantages of using color mapping function is it is resistant to outliers.

library(RColorBrewer)
mat2 = mat
mat2[1, 1] = 10
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow = 1, ncol = 2)))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1))
pheatmap2(mat2, newpage = FALSE)
upViewport()
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 2))
pheatmap2(mat2, col_fun = colorRamp2(seq(-3, 3, length.out = 7), 
    rev(brewer.pal(n = 7, name = "RdYlBu"))), newpage = FALSE)
upViewport(2)

Define column annotations and corresponding colors (same as pheatmap package)

annotation = data.frame(label1 = sample(c("a", "b"), 10, replace = TRUE),
                        label2 = sample(c("c", "d"), 10, replace = TRUE),
                        label3 = 1:10)
rownames(annotation) = colnames(mat)
annotation
pheatmap2(mat, annotation = annotation)

Set the annotation colors

annotation_colors = list(label1 = c("a" = "red", "b" = "blue"),
                         label2 = c("c" = "yellow", "d" = "green"))
annotation_colors
pheatmap2(mat, annotation = annotation, annotation_colors = annotation_colors)

Next, we will demonstrate how to add more heatmap. First generate an additional matrix

mat2 = matrix(runif(40), 10, 4)
colnames(mat2) = paste0("d", 1:4)

Plot the heatmap with the additional matrix. Arguments for the additional matrix are similar as the main matrix, but should be put into a list. E.g., col_fun is for the main matrix, then col_fun_list is for the additional matrix.

pheatmap2(mat, 
    legend_title = "mat", 

    mat_list = list(mat2 = mat2),
    col_fun_list = list(mat2 = colorRamp2(c(0, 0.5, 1), c("green", "white", "red"))),
    legend_title_list = "mat2")

As you can see, mat_list and col_fun_list should both be a named index and the name is used to map matrix to corresponding color function.

main is the title for the whole plot. sub_main is title for each heatmap. legend_title is the legend title for the main matrix and legend_title_list is the legend title for the additional matrix.

pheatmap2(mat, 
    legend_title = "mat", 
    main = "two heatmap", sub_main = c("mat1", "mat2"),

    mat_list = list(mat2 = mat2),
    col_fun_list = list(mat2 = colorRamp2(c(0, 0.5, 1), c("green", "white", "red"))),
    legend_title_list = "mat2")

Since pheatmap2 is modified from pheatmap, actually, all heatmap are stored in one big matrix and keep several columns empty to simulate gaps between heatmap. Thus here gap is the number of empty columns between two heatmap. gap can be a scalar or a vector correponding to gaps between every two heatmaps.

pheatmap2(mat, 
    legend_title = "mat", 
    gap = 3,

    mat_list = list(mat2 = mat2),
    col_fun_list = list(mat2 = colorRamp2(c(0, 0.5, 1), c("green", "white", "red"))),
    legend_title_list = "mat2")

Annotations for the additional matrix are also set as a list. If annotation is same for two heatmap, e.g., the first heatmap and the second both have label1 annotation, the legend for this annotation is only drawn once.

annotation2 = data.frame(label1 = c("a", "a", "b", "b"), label5 = 1:4)
rownames(annotation2) = colnames(mat2)
annotation_colors2 = list(label1 = c("a" = "red", "b" = "blue"))

The complex heatmap containing different annotations.

pheatmap2(mat,
    legend_title = "mat", 
    annotation = annotation, 
    annotation_colors = annotation_colors,

    mat_list = list(mat2 = mat2),
    col_fun_list = list(mat2 = colorRamp2(c(0, 0.5, 1), c("green", "white", "red"))),
    legend_title_list = "mat2",
    annotation_list = list("mat2" = annotation2),
    annotation_colors_list = list("mat2" = annotation_colors2))

Matrix can also be character. This provides a way to simulate column annotation. Internally, characters will be firstly converted to factors, then replaced as integer numbers and mapped from each level of factor to a color.

group = ifelse(rowMeans(mat) > 0, "high", "low")
gender = sample(c("male", "female"), nrow(mat), replace = TRUE)

For character matrix, colors can simply be specified as a list of colors and the order of colors correspond to levels of converted factors. In following, we set gap as a vector and set the second element to 0, so there will be no gap between group and gender heatmaps.

pheatmap2(mat, 
    legend_title = "mat", 

    mat_list = list(group = group, gender = gender),    
    col_fun_list = list(group = c("red", "blue"),
                        gender = c("orange", "pink")),
    legend_title_list = c("group", "gender"),
    gap = c(1, 0))

Finally, let's make a heatmap which contains everything.

pheatmap2(mat, 
    legend_title = "mat", 
    annotation = annotation, 
    annotation_colors = annotation_colors,

    mat_list = list(group = group, mat2 = mat2),
    col_fun_list = list(group = c("red", "blue"),
                        mat2 = colorRamp2(c(0, 0.5, 1), c("green", "white", "red"))),
    legend_title_list = c("group", "mat2"),
    annotation_list = list("mat2" = annotation2),
    annotation_colors_list = list("mat2" = annotation_colors2))


jokergoo/pheatmap2 documentation built on May 19, 2019, 7:25 p.m.