Home | Blog | Software | Publications | GitHub

In this post, we will demonstrate how to visualize mean signals in row clusters by **ComplexHeatmap** package.

First we load the packages and generate the random matrix.

```
library(ComplexHeatmap)
library(circlize)
library(RColorBrewer)
set.seed(123)
mat = cbind(rbind(matrix(rnorm(64, -1), 8), matrix(rnorm(64, 1), 8), matrix(rnorm(64, -1), 8)),
rbind(matrix(rnorm(64, 1), 8), matrix(rnorm(64, -2), 8), matrix(rnorm(64, -1), 8)),
rbind(matrix(rnorm(64, -0.5), 8), matrix(rnorm(64, -1), 8), matrix(rnorm(64, 1), 8)))
```

The random matrix contains three distinct subgroups by rows and following is how it looks by means of heatmap.

```
Heatmap(mat, name = "foo")
```

Next we are going to do little bit more to enhance the visual effect on the row clusters:

- split the heatmap by rows to separate row clusters.
- show and compare mean signals in the three row clusters.

We apply k-means clustering on rows. Although you can specify it by `km`

in `Heatmap()`

function, since
the partitioning information wil be used in several places, we calculate it in the first place.

```
km = 3
colors = brewer.pal(km, "Set1")
partition = kmeans(mat, centers = km)$cluster
```

We will put the mean signals in row clusters as a column annotation put on top of the heatmap.
This can be done by constructing a self-defined annotation function. The only input of this function
is `index`

which is the index of columns that will be automatically adjusted by column clustering or column reordering.

In following code, the basic logic is:

- calculate mean value in different row cluster,
- push a viewport to put graphics,
- add polygons which show the mean signals,
- add y-axis.

```
anno_col_mean = function(index) {
col_means = lapply(1:km, function(i) colMeans(mat[partition == i, index]))
n = length(index)
rg = range(unlist(col_means))
pushViewport(viewport(xscale = c(0.5, n + 0.5), yscale = rg))
grid.rect(gp = gpar(fill = "transparent"))
for(i in seq_along(col_means)) {
grid.polygon(c(1:n, n:1), c(col_means[[i]], rep(rg[1], n)),
gp = gpar(fill = paste0(colors[i], "80"), col = NA), default.units = "native")
}
grid.yaxis(gp = gpar(fontsize = 8))
upViewport()
}
ha = HeatmapAnnotation(col_mean = anno_col_mean)
```

Now we can put everything to make the new heatmap. In the heatmap, we specified `split = partition`

to
split the heatmap by k-means partition which has already be calculated. To make the correspondance
between signal lines and row clusters, we add a color bar on the right of the main heatmap.

```
Heatmap(mat, name = "foo", column_dend_side = "bottom", top_annotation = ha,
top_annotation_height = unit(2, "cm"), split = partition, show_row_names = FALSE) +
Heatmap(partition, col = structure(colors, names = as.character(1:km)), show_row_names = FALSE,
show_heatmap_legend = FALSE, name = "", width = unit(5, "mm"))
decorate_annotation("col_mean", {
grid.text("mean\nsignal", unit(-10, "mm"), rot = 90, just = "bottom")
})
```