# plotting two heatmaps with the same order of genes

I expected the same pattern but here I am not able to compare the patterns as the order of genes does not seem the same. I mean how I can have two heat maps on which the order of genes are the same so I woulds be able to compare the block of yellow and blue colors in two heat maps.

I have used this code

require("RColorBrewer")
myCol <- colorRampPalette(c("dodgerblue", "black", "yellow"))(100)
myBreaks <- seq(-2, 2, length.out=101)
heat <- t(scale(t(sc_DEGG)))
hr <- hclust(as.dist(1-cor(t(y), method="pearson")), method="complete")
heatmap.2(
heat,
Rowv=as.dendrogram(hr),
Colv=as.dendrogram(hc),
col=myCol,
breaks=myBreaks,
main="Title",
key=T,
keysize=1.0,
scale="none",
density.info="none",
reorderfun=function(d,w) reorder(d, w, agglo.FUN=mean),
trace="none",
cexRow=0.2,
cexCol=0.8,
distfun=function(x) dist(x, method="euclidean"),
hclustfun=function(x) hclust(x, method="ward.D2")
)

• Please use the 'code' format for code, it is more legible. And try to put the images directly in the text instead of link. – benn Jul 4 '18 at 16:03
• The MWE code here won’t work. Variables y and hc are not defined, even assuming that sc_DEGG is an unpublished genes x samples/cells matrix. – Tom Kelly Jul 8 '18 at 9:00

## 3 Answers

ComplexHeatmap is built for plotting side-by-side heat maps with the same clustering - you use the + notation, similar to ggplot2. To use the same example data as @b.nota:

library(ComplexHeatmap)
# First matrix
set.seed(2)
m <- replicate(8, rnorm(26))
rownames(m) <- letters[1:26]

# Second matrix
set.seed(3)
m2 <- replicate(8, rnorm(26))
rownames(m2) <- letters[1:26]

Heatmap(m) + Heatmap(m2)


And the results:

There are lots of examples in the extensive documentation.

EDIT:

To change colour scheme requires a call to the colorRamp2 function of the circlize package.

library(circlize)
mycol <- colorRamp2(c(-2,0,2), c("dodgerblue", "black", "yellow"))
Heatmap(m, col=mycol, cluster_columns = FALSE) +
Heatmap(m2, col=mycol, cluster_columns = FALSE)


This gives:

• Great solution! – benn Jul 5 '18 at 14:56
• @FereshTeh You can turn off the clustering on columns - cluster_columns = FALSE, then the ordering will be the same as the input matrix. As for colours, I've included a second example to show how they work in ComplexHeatmap (it's a bit different to your breaks example). – sjcockell Jul 5 '18 at 15:59
• @FereshTeh the number range in your colorRamp2 call should be informed by your data - you could use range() to get the min and max, for example. – sjcockell Jul 5 '18 at 17:53
• @FereshTeh I think this is probably veering into the territory of being a separate question. Since you have a few genes with high values in the 'T' matrix, they are washing out the colour scheme for the rest of the heatmap. You could set the max to be lower, and accept that those genes will saturate - the resulting heatmap will be less 'honest' about the data, but might capture what you want to see. – sjcockell Jul 6 '18 at 13:37
• Sorry, I have made a pair of heat maps based on your code in complexheatmap package. The right heat map is lighter than the left one. I don't know which one has been clustered based on the another one. How I can make the right one darker so that both seem more similar?? image.ibb.co/fbhVGo/Rplot311.png – Exhausted Jul 10 '18 at 21:25

You expect that the order of genes is the same for both heatmaps, but the chance is small that the 4000 genes will exactly be clustered in the same order.

What you can do, is use the order of genes (rows) from one heatmap and create a new heatmap with the other data set. You'll lose the tree of course because it will not be clustering anymore.

Here a small example:

library(gplots)

# First matrix
set.seed(2)
m <- replicate(8, rnorm(26))

rownames(m) <- letters[1:26]

hm <- heatmap.2(
m,
main="m",
key=T,
keysize=1.0,
scale="none",
trace="none",
density.info="none",
Colv = FALSE,
distfun=function(x) dist(x, method="euclidean"),
hclustfun=function(x) hclust(x, method="ward.D2")
)

# Second matrix
set.seed(3)
m2 <- replicate(8, rnorm(26))

rownames(m2) <- letters[1:26]

hm2 <- heatmap.2(
m2,
main="m2",
key=T,
keysize=1.0,
scale="none",
trace="none",
density.info="none",
Colv = FALSE,
distfun=function(x) dist(x, method="euclidean"),
hclustfun=function(x) hclust(x, method="ward.D2")
)

# Second matrix with row order of first
reorder_m2 <- m2[rev(hm$rowInd),] hm2_m <- heatmap.2( reorder_m2, main="m2 in m's order", key=T, keysize=1.0, scale="none", trace="none", density.info="none", Rowv = FALSE, Colv = FALSE, dendrogram="none", distfun=function(x) dist(x, method="euclidean"), hclustfun=function(x) hclust(x, method="ward.D2") )  • @FereshTeh hm is the output of the first heatmap (in your code it would be different) – llrs Jul 4 '18 at 20:25 • @Llopis, yeah sorry if that was not obvious. OP should save the heatmap to an object first like hm <- heatmap.2(... in my example. – benn Jul 4 '18 at 20:42 • Excuse me, when I use on my data says that reorder_m2 <- r[rev(hm$rowInd),] Error in r[rev(hm\$rowInd), ] : subscript out of bounds but the dimension of both matrices is the same :(( – Exhausted Jul 4 '18 at 20:52
• Sorry pheatmap(reorder_m2) Error in hclust(d, method = method) : must have n >= 2 objects to cluster because reorder_m2 does not anything in row just num[0,1:9} – Exhausted Jul 4 '18 at 21:02
• @FereshTeh, could you edit your question to include more code and explain when do you got these errors? – llrs Jul 4 '18 at 21:59

You have 2 options provided that both datasets have the same genes (rows):

1. Keep the original order of rows in the heatmap. If they’re in the same order in the dataset then they will be in the heatmap. You can suppress reordering with any of the following arguments to heatmap.2

Rowv = NULL

dendrogram = “col” or dendrogram = “none”

reorderfun = function(x) return(x)

1. You can compute the order of the genes (rows) in advance and pass them to the heatmap. The code shown in the question does this already with Rowv=as.dendrogram(hr). To have the same order in a second heatmap, you have to pass the same same dendrogram hr to both heatmaps. This can be computed from either dataset or another set of samples altogether.

Another option is to compute separate dendrograms (from hclust of each dataset) for the samples and combine them using merge. You can combine the datasets with cbind and plot the datasets together as one heatmap (with 2 sets of samples clustered separately) by passing the merged dendrogram to Colv:

#compute same dendrograms separately
hc1 <- hclust(as.dist(t(data1), method="euclidean")), method="complete")
hr2 <- hclust(as.dist(t(data2), method="euclidean")), method="complete")
mergedcols <- merge(as.dendrogram(hr1), as.dendrogram(hr2))
mergeddata <- cbind(data1, data2)
#compute gene dendrogram across all samples
hr <- hclust(as.dist(1-cor(t(mergeddata), method="pearson")), method="complete")
heatmap.2(
mergeddata,
Rowv=as.dendrogram(hr),
Colv=as.dendrogram(mergedcols),
col=myCol,
breaks=myBreaks,
main="Title",
key=T,
keysize=1.0,
scale="none",
density.info="none",
reorderfun=function(d,w) reorder(d, w, agglo.FUN=mean),
trace="none",
cexRow=0.2,
cexCol=0.8,
distfun=function(x) dist(x, method="euclidean"),
hclustfun=function(x) hclust(x, method="ward.D2")
)


You should be able to show the division between these samples with the colsep argument.