Heatmaps

Un heatmap es simplemente una representación gráfica en la que los valores de una matriz numérica son representados con una determinada escala de colores.

ggplot2 no tiene una función específica para los heatmaps pero pueden representarse usando geom_tile()

Hay dos puntos clave a la hora de representar un heatmap en ggplot2: transformar la matriz en un data.frame y elegir la escala de colores.

Creación y representación de un dataset mínimo

En primer lugar vamos a generar el dataset mínimo necesario para representarlo en ggplot2.

set.seed(1)
df.heatmap <- expand.grid(Var1 = letters[1:5], Var2 = 1:5)
df.heatmap$score <- runif(nrow(df.heatmap), min = -2, max = 2)

La función expand.grid genera un data.frame con todas las combinaciones posibles de los factores que les damos. En este caso, las 5 primeras letras del abecedario en minúsculas letters[1:5] = a, b, c, d, e y los números del 1 al 5. Luego generamos un vector aleatorio llamado score que es la variable que representaremos.

Para ello, como hemos dicho, usamos geom_tile()

library(ggplot2)
ggplot(df.heatmap, aes(x = Var1, y = Var2, fill = score)) + geom_tile()

Si echamos un vistazo a df.heatmap

head(df.heatmap)
##   Var1 Var2      score
## 1    a    1 -0.9379653
## 2    b    1 -0.5115044
## 3    c    1  0.2914135
## 4    d    1  1.6328312
## 5    e    1 -1.1932723
## 6    a    2  1.5935587

vemos que dicha estructura no es la habitual que asociamos a un heatmap, una matriz de datos. A continuación veremos como obtener este tipo de data.frames a partir de matrices de datos.

Transformar los datos

En primer lugar generamos una matriz de datos cuya estructura sea coherente con el data.frame anterior:

mat.heatmap = matrix(runif(25), ncol = 5, nrow = 5)
colnames(mat.heatmap) = 1:5
rownames(mat.heatmap) = letters[1:5]

head(mat.heatmap)
##            1         2         3         4         5
## a 0.38611409 0.4820801 0.6684667 0.8209463 0.7893562
## b 0.01339033 0.5995658 0.7942399 0.6470602 0.0233312
## c 0.38238796 0.4935413 0.1079436 0.7829328 0.4772301
## d 0.86969085 0.1862176 0.7237109 0.5530363 0.7323137
## e 0.34034900 0.8273733 0.4112744 0.5297196 0.6927316

Esta matriz podría ser la expresión génica de los genes a, b, c, d, e en las muestras 1:5. Ahora queremos convertir esta matriz en una estructura tipo

head(df.heatmap)
##   Var1 Var2      score
## 1    a    1 -0.9379653
## 2    b    1 -0.5115044
## 3    c    1  0.2914135
## 4    d    1  1.6328312
## 5    e    1 -1.1932723
## 6    a    2  1.5935587

para ello recurrimos a la función melt del paquete reshape. La función melt (y su inversa cast) permiten transformar una matriz entre sus formatos largo y ancho

require(reshape)
## Loading required package: reshape
mat.heatmap.m = melt(mat.heatmap)
head(mat.heatmap.m)
##   X1 X2      value
## 1  a  1 0.38611409
## 2  b  1 0.01339033
## 3  c  1 0.38238796
## 4  d  1 0.86969085
## 5  e  1 0.34034900
## 6  a  2 0.48208012
ggplot(data = data.frame(mat.heatmap.m), aes(x = X1, y = X2, fill= value)) + geom_tile()

La escala de colores

La otra parte crucial de un heatmap es la escala de colores. En un heatmap lo que se hace es asignar a cada valor númerico un tono diferente de color. Es decir, estamos generando un gradiente de colores a partir de los valores numéricos a representar. Por ello para modificarlo usaremos las funciones de la familia scale_fill_gradient()

df.heatmap <- expand.grid(Var1 = letters[1:10], Var2 = 1:10)
df.heatmap$score <- runif(nrow(df.heatmap), min = -2, max = 2)

Conscale_fill_gradient() podemos modificar los colores a usar en los valores mínimo y máximo de la variable y ggplot2 va a generar un gradiente con ellos.

ggplot(df.heatmap, aes(x = Var1, y = Var2, fill = score)) + geom_tile() + scale_fill_gradient(low = "white", high = "steelblue")

Para quitar el fondo gris del heatmap hay que hacer lo siguiente:

ggplot(df.heatmap, aes(x = Var1, y = Var2, fill = score)) + geom_tile() + scale_fill_gradient(low = "white", high = "steelblue") + scale_x_discrete(expand = c(0, 0)) + scale_y_continuous(expand = c(0,0))