Thanks Kevin, it works perfecctly!!
I have a question about how to change order of clusters on heatmap. I tried to make heatmap using Complex Heatmap package and I made K-mean clusters. my code is below:
HM <- Heatmap(matrix2, km = 4, show_row_names = FALSE, show_column_names = F, top_annotation = ha_column, cluster_columns = FALSE, show_heatmap_legend = T)
draw(HM, heatmap_legend_side = "right", show_annotation_legend = F)
I got this heatmap as below. https://ibb.co/jqGb77
In this example, I want to move cluster 2 to top, cluster 1 in 2nd top, cluster 3 on 3rd and cluster 4 on the bottom. How can I re-order the position of clusters ?
1 answer
I'm a big fan of ComplexHeatmap and again kudos to the developer for making it such a flexible package. However, I'm not immediately aware of a function that does (directly) what you want.
I would prefer to perform the k-means outside of the ComplexHeatmap package by just using kmeans(), and then manipulating the gene-to-cluster assignment vector in order to dictate the order of the clusters.
Create some random data (20 genes x 20 samples):
test <- matrix(rexp(400, rate=.3), ncol=20)
rownames(test) <- paste(rep("Gene", nrow(test)), 1:nrow(test), sep="")
colnames(test) <- paste(rep("Sample", ncol(test)), 1:ncol(test), sep="")
We then perform k-means with 4 centers and take a look at the gene-to-cluster assignment:
kclus <- kmeans(test, 4)
kclus$cluster
Gene1 Gene2 Gene3 Gene4 Gene5 Gene6 Gene7 Gene8 Gene9 Gene10 Gene11
3 3 2 1 2 1 3 1 2 1 4
Gene12 Gene13 Gene14 Gene15 Gene16 Gene17 Gene18 Gene19 Gene20
4 4 1 2 4 2 2 4 2
We then use the split parameter of Heatmap() in order to split the heatmap based on the k-means result:
split <- paste0("Cluster\n", kclus$cluster)
default.hmap <- Heatmap(test, split=split, cluster_row_slices = FALSE)
As we want to fix the order of the clusters, we have to re-order the gene-to-cluster assignment as a factor:
split <- factor(paste0("Cluster\n", kclus$cluster), levels=c("Cluster\n2","Cluster\n1","Cluster\n3","Cluster\n4"))
reorder.hmap <- Heatmap(test, split=split, cluster_row_slices = FALSE)
Then draw both the default-ordered and then re-ordered:
pushViewport(viewport(layout=grid.layout(nr=1, nc=2)))
pushViewport(viewport(layout.pos.row=1, layout.pos.col=1))
draw(default.hmap, newpage=FALSE)
upViewport()
pushViewport(viewport(layout.pos.row=1, layout.pos.col=2))
draw(reorder.hmap, newpage=FALSE)
upViewport()
upViewport()
And thank you for the question - I will re-use this code myself some time!
Thanks Kevin, this is very useful code.
I just tried this code with R 3.6.1 and ComplexHeatmap 2.0.0 and this code no longer works. The two heatmaps are now identical. EDIT: in the code above you forgot to set cluster_row_slices = FALSE
Thank you for alerting me to this. The code that I originally posted worked just fine when I posted my answer, ~18 months ago. cluster_row_slices either did not exist as a parameter in ComplexHeatmap at that time, or it existed and its default value was different. So, I had no need to include it then.
I have now edited the code in my answer (above) and it works with the latest ComplexHeatmap version.
The developer of ComplexHeatmap modified quite a few parameters and general functionality of the package in the relatively recent version change from Bioconductor 3.8 to Bioconductor 3.9 (we are now on the verge of Bioconductor 3.10).
Log in to answer this question.


For future reference: On
ibb.cosite scroll down and look for a tab that saysEmbed codes. Click onEmbed codes. Copy the code inHTML full imagebox. Post that line into your post here to parse the image in automatically (like above).Hi Kevin,
Thanks a lot for your post.
I am getting the following error, would you have an idea to fix it ?
Thanks a lot !
Please use
ADD COMMENT/ADD REPLYwhen responding to existing posts to keep threads logically organized.SUBMIT ANSWERis for new answers to original question.What is the size of the data-matrix that you are trying to plot?
You're right, adapting the size of the data-matrix was the key. Thanks a lot !
@Kevin Blighe, I would like to add my questions here if possible? 1. How I could show those four clusters in a colors-a color bar for each cluster as indicated for the sample clustering on the top of this post. 2. Then, is it possible to extract the cluster genes(for example cluster 1 in the above heatmaps) by calling the color bar? Theoretically, I am asking more or less a WGCNA approach of color assignment for each cluster of genes and extracting the cluster genes based on their color assignment? Thank you!
Open a new post, and please leave the answer field for answers only. Thank you.