Question: heatmap.2 reorder branches
gravatar for Benn
3.1 years ago by
Benn7.9k wrote:


I am using hierarchical clustering with heatmap.2, and would like to reorder the tree generated for the columns. I have searched here, on bioconductor, and on google but don't seem to find the right solution. Wondering if someone here knows how to manipulate the tree.

In more detail, I have clustered with the following code, and the column tree is perfect, except that I would like the red group left of the blue one (so between green and blue). I know from evolution biology class that these branches in theory can be turned (like a baby mobile). But I don't know how to do this with heatmap.2, I guess I would have to use the reorderfun, but don't know how?

heatmap.2(z_RPKM_ro, key = TRUE, col=blueyellow,"none"),
scale = c("none"), trace=c("none"), cexCol=1, cexRow=0.7, key.xlab="Row Z-score",
hclustfun = function(x) hclust(x, method = "ward.D"), dendrogram="both",
distfun = function(x) dist(x, method = "euclidean"),
labRow = F, RowSideColors = colorset, ColSideColors = colorBar2)

Thanks in advance!


ADD COMMENTlink modified 2.8 years ago by Xianjun270 • written 3.1 years ago by Benn7.9k

You could reorder the matrix and then plot it using heatmap.2

ADD REPLYlink written 3.1 years ago by Sej Modha4.6k

Thanks for your suggestion, but my point is the dendrogram. The dendrogram is showing that the replicates of my groups cluster nice together. Of course I can manually reorder the matrix/heatmap, but will lose then the information of the dendrogram.

Is it possible to rearrange the dendrogram horizontally? Since the distance is depicted vertically, it won't mess up the outcome of the dendrogram.

ADD REPLYlink modified 3.1 years ago • written 3.1 years ago by Benn7.9k
gravatar for e.rempel
3.0 years ago by
Germany, Heidelberg, COS
e.rempel800 wrote:

Hi b.nota,

my response is kind of late, but here it is. I assume one possible way is to pass explicitly reordered dendrogram as a parameter to function heatmap.2. Let me show it with the following example:

x <- as.matrix(mtcars)
heatmap.2(x, margins = c(5,10))

On my machine, I obtain following graphic

enter image description here

Now just assume I would like to swap some branches to have Ferrari Dino at the bottom and Duster 360 at the top of row dendrogram. In your case, you would like to swap red and blue samples. For this purpose, I first recalculate the actual row dendrogram

row.hc <- hclust(dist(x))
row.dd <- as.dendrogram(row.hc)

Now I manually assign weights to specific columns

weights.dd <- ifelse(rownames(x) == "Ferrari Dino", yes = 1, no = 50) + ifelse(rownames(x) == "Duster 360", yes = 950, no = 0)

This line ensures that Ferrari Dino gets weight 1 and Duster 360 weight 1000. In your case you could manually assign weight 1 to brown samples, weight 10 to green, 100 to red, and 1000 to blue (I am not sure about this, you have to find it out). Now I use the function reorder to reorder the row dendrogram

row.dd.reordered <- reorder(row.dd, wts = weights.dd, agglo.FUN = mean)

and use it for the new call of heatmap.2

heatmap.2(x, Rowv = row.dd.reordered, margins = c(5,10))

Then I obtain the following graphic

enter image description here


ADD COMMENTlink written 3.0 years ago by e.rempel800

Hi e.rempel,

Thank you for your suggestion. Your example does seem to work indeed, do you know how I can find the right values for my tree?

ADD REPLYlink written 3.0 years ago by Benn7.9k

Hi, I had always to find it experimentally ;). I have assigned some weights to samples, reordered dendrogram and plotted it. It it was ok, I passed it to call of heatmap.2. Unfortunately, I dont know the direct way of computing these values.

ADD REPLYlink written 3.0 years ago by e.rempel800
gravatar for Xianjun
2.8 years ago by
Great Boston Area
Xianjun270 wrote:

I had the same problem of using the order function with proper weight, and I just figured out the trick.

Taking the mtcars dataset in e.rempel's example above, we first run the default hclust to get the dendrogram.

x <- as.matrix(head(mtcars))  # only using the first 6 cars for demo purpose
row.hc <- hclust(dist(x))
row.dd <- as.dendrogram(row.hc)

enter image description here

> labels(row.dd)  # dendrogram leaves
[1] "Hornet Sportabout" "Hornet 4 Drive"    "Valiant"           "Datsun 710"       
[5] "Mazda RX4"         "Mazda RX4 Wag" 
# Note that this is differt from 
> rownames(x)  # original data labels
[1] "Mazda RX4"         "Mazda RX4 Wag"     "Datsun 710"        "Hornet 4 Drive"   
[5] "Hornet Sportabout" "Valiant" 
> order.dendrogram(row.dd)  # the index of dendrogram leaves in original data
[1] 5 4 6 3 1 2

To mimic the dendrogram leaves via recorder(), we have to call order() to get the order of the index. This is the trick!! e.g.

plot(reorder(row.dd, wts = order(order.dendrogram(row.dd))))

This will reproduce the same plot as plot(row.dd) above.

From this, I learned that, if I want to reorder the tree leaves in a new order, e.g. "Hornet Sportabout", "Valiant","Hornet 4 Drive","Mazda RX4", "Mazda RX4 Wag", "Datsun 710". I will first need to get its index in the original data labels using match(), then call order() to the order of the index, finallly run reorder() with the new order. Here is it:

neworder = c("Hornet Sportabout", "Valiant","Hornet 4 Drive","Datsun 710","Mazda RX4", "Mazda RX4 Wag")
row.dd.reordered  = reorder(row.dd, wts = order(match(neworder, rownames(x))))

enter image description here

ADD COMMENTlink written 2.8 years ago by Xianjun270

Great! Thanks for explaining it. I actually wanted to move whole branches (containing more leafs). Like in your example put the mazda group before Datsun.

neworder = c("Hornet Sportabout", "Valiant", "Hornet 4 Drive", "Mazda RX4", "Mazda RX4 Wag", "Datsun 710")
row.dd.reordered  = reorder(row.dd, wts = order(match(neworder, rownames(x))))

But that doesn't seem to work...


ADD REPLYlink modified 2.8 years ago • written 2.8 years ago by Benn7.9k

Hi b.note,

I assume it doesn't work since reorder (or actually reorder.dendrogram) agglomerate node weights to obtain "weights" of branches/subtrees. Per default, agglomeration function summarizes the weights, thus to put a specific branch before the others, you might need to assign a very high value.

ADD REPLYlink written 2.8 years ago by e.rempel800

Yeah it doesn't work, with reorder function you can only switch two leafs in the same branch. I wanted to switch whole branches containing more leafs per branch.

I have tried your weights approach, but can't find the right settings to get exactly the same branches but then switched.

Thanks anyway all for your suggestions!

ADD REPLYlink written 2.8 years ago by Benn7.9k

Sorry to hear that. I had always to experiment with the weights to get the order of branches I want. Maybe it is worth trying different agglo.FUN in reorder (e.g. mean or max)?

ADD REPLYlink written 2.8 years ago by e.rempel800
gravatar for ivivek_ngs
3.0 years ago by
Seattle,WA, USA
ivivek_ngs4.9k wrote:

If you want to use different forms of dendrogram then pheatmap package is good to try out which has some sets of methods that can cluster the columns or the rows in different dendrogram based approaches. However if you want to cluster base on your groups for the columns that categorize your columns in that case make an annotation dataframe that groups your samples into the categories and use that to arrange the data in pheatmap switching off the classical clustering method. That will make you understand how the data is organised with your own clustering , in this case your unsupervised clustering is not working.

ADD COMMENTlink written 3.0 years ago by ivivek_ngs4.9k
Please log in to add an answer.


Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1259 users visited in the last hour