jokergoo / ComplexHeatmap

Make Complex Heatmaps
https://jokergoo.github.io/ComplexHeatmap-reference/book/
Other
1.29k stars 224 forks source link

How to split the heatmap based on dendextend::cuttree clusters? #32

Closed minisciencegirl closed 8 years ago

minisciencegirl commented 8 years ago

I am using dendextend to cut my hierarchical clustering dendrograms and want to split the heatmap accordingly. Can I use Heatmap to do this? I know I can do this if I subset the matrix and plot the heatmap with the subset of data...

hr <- hclust(dist(mat_FC), method = "average") clusters <- dendextend::cutree(hr, k = 100) row_dend = hr col_dend = hclust(dist(t(mat_FC)), method = "average") Heatmap(mat_FC, col = colorRamp2(c(-10, 0, 10), c("blue", "#EEEEEE", "red"), space = "RGB"), cluster_rows = color_branches(row_dend, k = 100), cluster_columns = color_branches(col_dend, k =2), show_row_names = FALSE, split =100)

However, I am getting the following error: Error in valid.viewport(x, y, width, height, just, gp, clip, xscale, yscale, : invalid 'xscale' in viewport

Thanks!!

jokergoo commented 8 years ago

Hi,

You can pass clusters to split options:

set.seed(12345)
mat = matrix(rnorm(100), nr = 25)

hr = hclust(dist(mat), method = "average")
clusters = dendextend::cutree(hr, k = 5)

Heatmap(mat, split = clusters)
jokergoo commented 8 years ago

another way is to mark subtrees with different colors instead of splitting the heatmap

set.seed(12345)
mat = matrix(rnorm(100), nr = 25)

hr <- hclust(dist(mat), method = "average")
hr = as.dendrogram(hr)
clusters <- dendextend::cutree(hr, k = 5)

Heatmap(mat, name = "foo", cluster_rows = hr)

add_alpha = function(col, alpha = 0.5) {
    rgb(t(col2rgb(col)/255), alpha=alpha)
}
decorate_row_dend("foo", {
    ind = clusters[order.dendrogram(hr)]

    first_index = function(l) which(l)[1]
    last_index = function(l) { x = which(l); x[length(x)] }

    x1 = sapply(1:5, function(i) first_index(ind == i)) - 1
    x2 = sapply(1:5, function(i) last_index(ind == i))

    grid.rect(y = 1-x1/length(ind), height = (x2 - x1)/length(ind), just = "top",
        default.units = "npc", gp = gpar(fill = add_alpha(1:5, 0.2), col = NA))
})

test

minisciencegirl commented 8 years ago

Thanks for the suggestion.

I think given that my matrix is quite large, I was hoping to split the tree into smaller subtree rather than highlighting the dendrogram with different colours.

Unfortunately when I tried passing the split = clusters to the Heatmap( ), I am now getting a different error: Error in object@row_dend_list[[k]] : subscript out of bounds

The toy dataset works for me - is there a limit to the size of dataframe that I can plot with Heatmap?

jokergoo commented 8 years ago

Is it possible for you to send me the data matrix? I simulated a huge matrix and split into 100 pieces and it works fine.

On the other hand, why do you want to split rows into 100 parts? I think it is not a good way for visualization. (See following heatmap, the heatmap is split into 100 parts)

test

minisciencegirl commented 8 years ago

Hmm I see what you meant. It doesn't really look that great.

Just sent you an email with the dataframe to your gmail.