I am working with large matrices that I want to plot using heatmaps.
My first attempts were done by using pheatmap that rendered exactly the plots I wanted. Unfortunately, when working with larger matrices, pheatmap is not ideal (very slow) and thus I wanted to try out heatmap3 instead (based on this Stack-overflow question).
My question is how can I replicate a pheatmap figure using heatmap3. The major problem that I am facing is with the legends that are incomplete using the heatmap3.
Bellow is the complete description of my problem with a toy example:
Here is the data I am working with:
set.seed(1234)
# set the data:
# Create a 9x9 matrix:
nrow_ <- 9; ncol_ <- 9
data <- matrix(runif(nrow_ * ncol_), nrow=nrow_, ncol = ncol_)
rownames(data) <- seq(1, nrow_, 1)
colnames(data) <- seq(1, ncol_, 1)
# Transforme the matrix into a disimilarity matrix
data[lower.tri(data)]<-data[upper.tri(data)]
diag(data) <- 0
# set the coldata
coldata <- data.frame(
category = c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
row.names = seq(1, ncol_, 1))
# set the color map
color_map <- c("red", "blue", "green")
names(color_map) <- c("A", "B", "C")
# set the coldata categories' color
coldata$colors <- as.character(color_map[coldata$category])
As you can see, we have a 9x9 (symetric) dissimilarity matrix (data) and a column description dataframe (coldata) linking every column (number from 1 to 9) to a category ("category" column with levels A, B and C).
We also have a color map (color_map) that links every category (A, B and C) to some color (red, blue, green).
I can plot this matrix using pheatmap as follows:
library(pheatmap)
pheatmap(mat = data,
clustering_distance_rows = as.dist(data),
clustering_distance_cols = as.dist(data),
clustering_method = "average", scale = "none",
show_colnames = T, show_rownames = T,
cluster_cols = T, cluster_rows = T,
annotation_col = coldata[, "category", drop=F],
treeheight_row = 50, treeheight_col = 50,
annotation_colors = list(category = color_map))
Note that since that data is already a "distance" matrix, I set the clustering_distance_rows and clustering_distance_cols as the input data (as.dist(data)).
You may also appreciate here the two legends information:
- First legend shows the color-bar explaining the colors in the matrix
- Second legend shows the column's annotations colors
Now in heatmap3 I can replicate part of the figure using:
library(heatmap3)
heatmap3(x = data, symm = T, scale = "none",
distfun = as.dist, hclustfun = hclust, method = "average",
showColDendro = T, showRowDendro = T,
ColSideColors = coldata$colors, ColSideAnn = coldata$category,
useRaster = F)
Unfortunately, here I only see the color-bar but not the legend explaining the column's categories.
As described in heatmap3's vignette (link), we can add the legend of the column's categories using the legendfun variable.
heatmap3(x = data, symm = T, scale = "none",
distfun = as.dist, hclustfun = hclust, method = "average",
showColDendro = T, showRowDendro = T,
ColSideColors = coldata$colors, ColSideAnn = coldata$category,
useRaster = F,
legendfun = function(){
showLegend(legend=names(color_map),
col=as.character(color_map),
cex=1.5)
})
Unfortunately here we only see the legend of the column's categories but we do not see the color-bar.
So my question is: Using heatmap3, how can I see both legends: 1) The color-bar and 2) the column's categories?
Another additional question would also be to know how to have the same color-bar from pheatmap using heatmap3.