Question: Heat Map With Two Color Scales
1
5.8 years ago by
Assa Yeroslaviz1.2k
Munich
Assa Yeroslaviz1.2k wrote:

Hi,

I was wondering whether it's possible to have a heatmap in R with two different colour scales.

I have two experiments with two different results of a different scale. The ID list list is the same. I would like to plot them both on the same image if possible. But as they are of different values, I can't plot them on the same scale.

I would like the heatmap to have a different scale and a different colour-space. The fist one is from -10 to 10 and should have e.g. the colour scale green-red. the second is from -3 to 3 and should be plotted in yellow-blue colour space.

Is something like that possible?

Thanks

Assa

R heatmap • 8.6k views
modified 20 months ago by Biostar ♦♦ 20 • written 5.8 years ago by Assa Yeroslaviz1.2k
7
5.8 years ago by
Bergen, Norway
Michael Dondrup46k wrote:

Yes it is possible to plot using heatmap or heatmap.2 with a different color scheme for each column, but not without some trickery.

First, you have to scale your columns to unit variance, because it would be a mistake not scale data used for clustering if we already know they are on a different scale. Most distance measures are sensitive to differences in variance between the variables and your first experiment has a much larger range than the second one. If both distributions are approximately normal or at least central, it is reasonable to assume that the first variable has also a larger variance and will therefore dominate the cluster analysis.

``````library(gplots)
### make some example data
x = matrix(c(runif(10, -10, 10), runif(10,-3,3)), ncol=2)
### scale the matrix
xs = scale(x)
### save the dendrogram:
row.dend = as.dendrogram(hclust(dist(xs)))
### make a single color scale red-black-green, yellow-white-blue
mycols = c(colorRampPalette(c("red","black","green"))(10),  colorRampPalette(c("yellow","white","blue"))(10))
# did I say that this was ugly?
# adjust columns of xs to plot:
xs[,1] = xs[,1] - max(xs[,1]) - 0.1 # make sure they are far away enough from 0!
xs[,2] = xs[,2] - min(xs[,2]) + 0.1
## control color breaks are centered at 0 and override automatic color breaks,
## which can result in use of wrong color on either side depending on distribution
breaks = (seq (-1,1, length=21))
## plot:
heatmap.2(xs, col = mycols, Rowv = row.dend, dendrogram="row", scale="none", breaks=breaks)
## compare this to the outcome using a single color scheme which is much more intuitive
heatmap.2(x, dendrogram="row", scale="column", col=colorRampPalette(c("yellow","white","blue"))(20))
``````

Oh, and did I say that this solution stinks (you have to adjust color generation, or generate color breaks manually), even more so if you try to extend it to more than two colors. You get all sorts of problems with the values close to 0 now, also the cluster result doesn't look very convincing now, but in the end, this plot shows, why you shouldn't use different color-schemes in a single heatmap. (Also there is a difference in the dendrogram between both approaches, need some time to find out why).

The best way would be to make a derived version of `heatmap.2` or `image`, that supports a list for its `col` argument, allowing to pass one color vector for each column, please go ahead ;P

tl;dr: Yes it is possible, but you don't want to do it.