Chapter 10

Heatmap: Static and lnteractive

Un mapa de calor, también conocido como mapa de color falso, es una forma de visualizar la agrupación jerárquica mediante una escala de color. Permite mostrar simultáneamente grupos de muestras y características.

El agrupamiento jerárquico se realiza tanto para las filas como para las columnas de la matriz de datos. Luego, se reordenan las columnas/filas de acuerdo con el resultado del agrupamiento, colocando las observaciones similares cerca unas de otras.

Los bloques de valores “altos” y “bajos” son adyacentes en la matriz de datos. Por último, se aplica un esquema de color para la visualización y se muestra la matriz de datos; aquí se demostrará cómo dibujar y organizar un mapa de calor.

10.1 R Packages/functions for drawing heatmaps

Para dibujar mapas de calor tenemos estas distintas funciones:

  • heatmap: Este dibuja un mapa de calor simple.

  • heatmap.2: Dibuja un mapa de calor mejorado en comparación con el base inicial heatmap.

  • pheatmap(): Presenta mapas de calor y proporciona más control para cambiar la apariencia .

  • d3heatmap(): Dibuja un mapa de calor interactivo en el que se puede hacer clic.

  • Heatmap(): Anota y organiza mapas de calor complejos, esto es muy útil para el análisis de datos genómicos.

10.2 Data preparation

Usamos datos de mtcars el cual es un conjunto de datos incorporado que contiene información sobre diferentes modelos de automóviles, y que contiene 32 filas (representando diferentes modelos de automóviles) y 11 variables o columnas que describen diferentes características de los automóviles como lo son:

  • `mpg`: Millas por galón (consumo de combustible).

  • `cyl`: Número de cilindros.

  • `disp`: Desplazamiento (en pulgadas cúbicas).

  • `hp`: Caballos de fuerza.

  • `drat`: Relación del eje trasero.

  • `wt`: Peso (en miles de libras).

  • `qsec`: Tiempo de cuarto de milla.

  • `vs`: Tipo de motor (0 = motor en V, 1 = motor en línea).

  • `am`: Tipo de transmisión (0 = automático, 1 = manual).

  • `gear`: Número de engranajes.

  • `carb`: Número de carburadores.

df <- scale(mtcars)

10.3 R base heatmap: heatmap()

Podemos usar la función R heatmap() un grafico simplificado, siendo:

  • x : una matrix numerica

  • Scale: Nos Indica si los valores deben estar centrados y escalados en la dirección de la fila o en la dirección de la columna, o ninguno. Los valores permitidos están en c(“row”, “column”, “none”). El valor predeterminado es “row”.

suppressPackageStartupMessages(library(gplots))

library(gplots)
x <- scale(df)
heatmap(x, scale = "row")

heatmap(df, scale = "none")

Podemos especificar una paleta de colores usando el argumento col.

col<- colorRampPalette(c("red", "white", "blue")) (256)
library("RColorBrewer")
col <- colorRampPalette (brewer.pal(10, "RdYlBu")) (256)

Además, puede usar el argumento RowSideColors y ColSideColors para anotar filas y columnas, respectivamente.

# Use RCoLorBrewer coLor paLette names
library("RColorBrewer")
col <- colorRampPalette (brewer.pal(10, "RdYlBu"))(256)

heatmap(df, scale = "none", col= col,
RowSideColors = rep(c("blue", "pink"), each = 16) ,
ColSideColors = c(rep("purple", 5), rep("orange", 6)))

10.4 Enhanced heat maps: heatmap.2()

library("gplots")
heatmap.2(df, scale = "none", col = bluered(100), 
          trace = "none", density.info = "none")

10.5 Pretty heat maps: pheatmap()

Cortamos el mapa de calor a la agrupación que deseamos, en este caso es de 4 filas, este valrlo lo podemos ir cambiando para ser mas especificos en las filas que queremos mostrar o en grupos.

library( "pheatmap")
pheatmap(df, cutree_rows = 4 )

10.6 Interactive heat maps: d3heatmap()

El paquete d3heatmap no sirve porque el paquete lo sacaron del repositorio CRAN.

Este paquete nos permite intecartuar mas con el mapa, en el sentido de acerle zoom a una area especifica, o dar click en alguna celda para ver la información de ella.

#install.packages("d3heatmap")#
#library("d3heatmap" )#
#d3heatmap(scale(mtcars), colors = "RdYlBu" ,#
#k_row = 4, # Number of groups in rows#
#k_col = 2 # Number of groups in columns#

10.7 Enhancing heatmaps using dendextend

Podemos usar tambien el paquete dendextend para mejorar lo que muestran los otros paquetes, para esto los datos que estamos utilizando que son los de mtcars le definiremos un orden a la apariecnia de las filas y las columnas usando el paquete de dendextend este primer paso lo haremos con el siguiente codigo:

library(dendextend)
## 
## ---------------------
## Welcome to dendextend version 1.17.1
## Type citation('dendextend') for how to cite the package.
## 
## Type browseVignettes(package = 'dendextend') for the package vignette.
## The github page is: https://github.com/talgalili/dendextend/
## 
## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
## You may ask questions at stackoverflow, use the r and dendextend tags: 
##   https://stackoverflow.com/questions/tagged/dendextend
## 
##  To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
## ---------------------
## 
## Attaching package: 'dendextend'
## The following object is masked from 'package:stats':
## 
##     cutree
# order for rows
Rowv  <- mtcars %>% scale %>% dist %>% hclust %>% as.dendrogram %>%
   set("branches_k_color", k = 3) %>% set("branches_lwd", 1.2) %>%
   ladderize
# Order for columns: We must transpose the data
Colv  <- mtcars %>% scale %>% t %>% dist %>% hclust %>% as.dendrogram %>%
   set("branches_k_color", k = 2, value = c("orange", "blue")) %>%
   set("branches_lwd", 1.2) %>%
   ladderize
  1. la función normal es el heatmap , esta agrupa en ramas las filas y las columnas, y esas ramas las agrupa en arboles como en el capitulo anterior; cambia el colors de los arboles y del mapa para poder distinguir a detalle cada celda y su valor.
heatmap(scale(mtcars), Rowv = Rowv, Colv = Colv,
        scale = "none")

  1. la funcion heatmap.2 mejora la presentación de la función base heatmap.
library(gplots)
heatmap.2(scale(mtcars), scale = "none", col = bluered(100), 
          Rowv = Rowv, Colv = Colv,
          trace = "none", density.info = "none")

10.8 Complex heatmap

Nos proporciona una solución para crear y visuRColorBrewer:alizar múltiples mapas de calor, también permite hacer la asociación entre diferentes datos de diferentes fuentes.

  • Mostramos un mapa de calor simple:
suppressPackageStartupMessages(library(ComplexHeatmap))

library(ComplexHeatmap)

Heatmap(df, 
        name = "mtcars", #title of legend
        column_title = "Variables", row_title = "Samples",
        row_names_gp = gpar(fontsize = 7) # Text size for row names
        )

  • Tambien podemos personalizar el color con la función colorRamp2 de la siguiente manera:
suppressPackageStartupMessages(library(circlize))

library(circlize)

mycols <- colorRamp2(breaks = c(-2, 0, 2), 
                    colors = c("green", "white", "red"))
Heatmap(df, name = "mtcars", col = mycols)

O cambiar la paleta de colores con la función RColorBrewer:

library("circlize")
library("RColorBrewer")
Heatmap(df, name = "mtcars",
        col = colorRamp2(c(-2, 0, 2), brewer.pal(n=3, name="RdBu")))

Y finalmente podemos cambiar la apariencia de los dendogramas para poder indentificarlos mejor:

library(dendextend)
row_dend = hclust(dist(df)) # row clustering
col_dend = hclust(dist(t(df))) # column clustering
Heatmap(df, name = "mtcars", 
        row_names_gp = gpar(fontsize = 6.5),
        cluster_rows = color_branches(row_dend, k = 4),
        cluster_columns = color_branches(col_dend, k = 2))

10.8.2 Splitting heatmap by rows

Podemos dividir el mapa de calor utilizando el algoritmo k-means o una variable de agrupación. Es importante que utilicemos la función set.seed para que los resultados obtenidos puedan reproducirse con precisión.

  • Dividiremos el dendograma usando el k-means , en este caso lo dividiremos en 2, pero tambien depende del usuario en cuantos filas quiere hacer visualizar a detalle.
# Divide into 2 groups
set.seed(2)
Heatmap(df, name = "mtcars", k = 2)

  • En caso para dividir una variables de agrupación utilizamos el argumento split
# split by a vector specifying rowgroups
Heatmap(df, name = "mtcars", split = mtcars$cyl,
        row_names_gp = gpar(fontsize = 7))

# Split by combining multiple variables
Heatmap(df, name ="mtcars", 
        split = data.frame(cyl = mtcars$cyl, am = mtcars$am),
        row_names_gp = gpar(fontsize = 7))

  • Si queremos utilizar otro metodo de aparte del K-meas, lo podemos hacer si asignamos un vector para esta partición, en este caso sería pam, este partirá los datos del cluster, se podría decir que es una versión mas constituida del k-means.

10.8.3 Heatmap annotation

La clase HeatmapAnnotation se utiliza para darle la anotación en una fila o columna, Un formato simplificado es:

#HeatmapAnnotation(df, col, show_legend)#
df <- t(df)

10.8.3.1 Simple annotation

Un vector en este caso tiene valores discretos o continuos y se utiliza para anotar filas o columnas. Vamos a utilizar las variables cualitativas cyl (niveles = “4”, “6” y “8”) y am (niveles = “0” y “1”), y la variable continua mpg para anotar columnas; estas 3 variables tienen colores personalizados para distinguirlas

# Define colors for each levels of qualitative variables
# Define gradient color for continuous variable (mpg)
col = list(cyl = c("4" = "green", "6" = "gray", "8" = "darkred"),
            am = c("0" = "yellow", "1" = "orange"),
            mpg = circlize::colorRamp2(c(17, 25), 
                                       c("lightblue", "purple")) )
# Create the heatmap annotation
ha <- HeatmapAnnotation(
  cyl = mtcars$cyl, am = mtcars$am, mpg = mtcars$mpg,
  col = col
)
# Combine the heatmap and the annotation
Heatmap(df, name = "mtcars",
        top_annotation = ha)

10.8.3.2 Complex annotation

Aquí se combina el mapa de color con graficos basicos que muestran la distribición de los datos, las funciones para esto son las siguientes: anno_pointsanno_barplotanno_boxplotanno_densityanno_histogram.

# Define some graphics to display the distribution of columns
.hist = anno_histogram(df, gp = gpar(fill = "lightblue"))
.density = anno_density(df, type = "line", gp = gpar(col = "blue"))
ha_mix_top = HeatmapAnnotation(
  hist = .hist, density = .density,
  height = unit(3.8, "cm")
  )

# Define some graphics to display the distribution of rows
.violin = anno_density(df, type = "violin", 
                       gp = gpar(fill = "lightblue"), which = "row")
.boxplot = anno_boxplot(df, which = "row")
ha_mix_right = HeatmapAnnotation(violin = .violin, bxplt = .boxplot,
                              which = "row", width = unit(4, "cm"))

# Combine annotation with heatmap
Heatmap(df, name = "mtcars", 
        column_names_gp = gpar(fontsize = 8),
        top_annotation = ha_mix_top) + ha_mix_right

  • Los histogramas muestran la distribución de los valores en cada columna del dataframe df, y representan la frecuencia de los valores en un rango específico.

  • Las curvas de densidad representan la distribución de la probabilidad de los valores en cada columna del dataframe df, y muestran la forma de la distribución en que podemos identificar picos, asimetrías o colas largas.

  • Los diagramas de violín muestran información sobre la mediana, los cuartiles, los valores atípicos y la forma de la distribución en cada fila.

  • Los diagramas de caja muestran la mediana, los cuartiles y los valores atípicos, lo que permite tener una idea de la dispersión y la simetría de los datos en cada fila.

10.8.3.3 Combining multiple heatmaps

Organizamos los mapas de la siguiente manera:

# Heatmap 1
ht1 = Heatmap(df, name = "ht1", km = 2,
              column_names_gp = gpar(fontsize = 9))
# Heatmap 2
ht2 = Heatmap(df, name = "ht2", 
        col = circlize::colorRamp2(c(-2, 0, 2), c("green", "white", "red")),
        column_names_gp = gpar(fontsize = 9))
# Combine the two heatmaps
ht1 + ht2

hay que tener en cuenta que cuando combinamos varios mapas de calor, el primer mapa se considera el principal, el mapa restante en ocasiones se ajusta automaticamente a la configuración del mapa principal y es posible que se eliminen grupos de filas.

10.9 Application to gene expression matrix

En los datos de expresión génica, las filas son genes y las columnas son muestras, los graficos muesran más información sobre los genes después del mapa de calor , la longitud del gen y el tipo de genes.

expr <- readRDS(paste0(system.file(package = "ComplexHeatmap"),
                      "/extdata/gene_expression.rds"))
mat <- as.matrix(expr[, grep("cell", colnames(expr))])
type <- gsub("s\\d+_", "", colnames(mat))
ha = HeatmapAnnotation(
  df = data.frame(type = type),
   annotation_height = unit(4, "mm")
  )

Heatmap(mat, name = "expression", km = 5, top_annotation = ha,
    show_row_names = FALSE, show_column_names = FALSE) +
Heatmap(expr$length, name = "length", width = unit(5, "mm"),
    col = circlize::colorRamp2(c(0, 100000), c("white", "orange"))) +
Heatmap(expr$type, name = "type", width = unit(5, "mm")) +
Heatmap(expr$chr, name = "chr", width = unit(5, "mm"),
    col = circlize::rand_color(length(unique(expr$chr))))
## There are 23 unique colors in the vector `col` and 23 unique values in
## `matrix`. `Heatmap()` will treat it as an exact discrete one-to-one
## mapping. If this is not what you want, slightly change the number of
## colors, e.g. by adding one more color or removing a color.

10.10 Summary

Usamos muchas funciones para dibujar mapas de calor (desde mapas de calor básicos hasta complejos). Se puede representar un mapa de calor básico utilizando la función heatmap o la función heatmap.2.
La función pheatmap, en el paquete del mismo nombre se usa para crear mapas de calor mas interactivos, donde uno tiene un mejor control sobre algunos parámetros gráficos como el tamaño de la celda.

y finalmente la función Heatmap nos permite dibujar, anotar y organizar fácilmente mapas de calor complejos.