Question: R Heatmaps: Non-Linear Mapping Between Colors And Values
2
7.4 years ago by
Irsan7.2k
Amsterdam
Irsan7.2k wrote:

I am thankful for How Do I Draw A Heatmap In R With Both A Color Key And Multiple Color Side Bars? in R where you can add row and column information together with the color mapping information. I use it all the time to make pictures of hierarchically clustered expression profiles measured by expression arrays.

Usually I scale the input matrix on rows (probesets) to Z-scores in order to make weigh equally in the clustering. The colors of the heatmap are mapped linearly to the Z-scores. \

The problem is, when you have a few extremes in your data set, they tend to make your heatmap a little faint. In the attached heatmap you can see that the Z-scores range from somewhere around -10 to 10, however, about 99% is in the range of -4 to 4. I would like to change the way colors are mapped to the Z-scores in such a way that the green-to-red goes from -4 to 4 and the colors of the Z-scores outside this range just do not become any more green or red then they are already, any ideas?

``````# import gplots for greenred colors
library(gplots)
# generate random matrix
x<-replicate(100,rnorm(100,0,1))
# draw heatmap
heatmap.3(x,density.info="histogram",col=greenred)
# introduce outliers
x[1,1] <- -10
x[2,2] <- 10
# draw heatmap with outliers
heatmap.3(x,density.info="histogram",col=greenred)
``````

R heatmap • 23k views
modified 7.4 years ago • written 7.4 years ago by Irsan7.2k
9
7.4 years ago by
Simon Cockell7.3k
Newcastle
Simon Cockell7.3k wrote:

You can use the `breaks` argument to do this, from the `heatmap.2` documentation:

breaks (optional) Either a numeric vector indicating the splitting points for binning x into colors, or a integer number of break points to be used, in which case the break points will be spaced equally between min(x) and max(x)

To use to achieve your desired effect:

``````#breaks for the core of the distribution
breaks=seq(-4, 4, by=0.2) #41 values
breaks=append(breaks, 10)
breaks=append(breaks, -10, 0)
#create colour panel with length(breaks)-1 colours
mycol <- colorpanel(n=length(breaks)-1,low="green",mid="black",high="red")
#now plot heatmap - I'm using heatmap.2, but am assuming this will work with Obi's heatmap.3
heatmap.2(x,density.info="histogram",col=mycol, trace='none', breaks=breaks)
``````

The major drawback is that the outliers are a lot less obvious, but clearly the heatmap overall is a lot less 'washed out'.

Results:

Before

After

Thanks, thats it!

It's like a learning time machine. 16 months on and this is exactly what I needed. Thanks!

1
7.4 years ago by
Belgium, Brussels
Nicolas Rosewick9.2k wrote:

you could simply change your matrix by changing all value over 4 to 4 and all value under -4 to -4

Or write a little function

``````plotHeatmap <- function(M,up=4,down=-4){
M[M>up]<- up
M[M<(-down)]<- down
print(heatmap.3(M,density.info="histogram",col=greenred))
}
``````

I tried that with my real data but then what happens is that the resulting clustering does not correspond to the biological situation any more. The values should remain the same, they reflect the expression profiles found in the samples.

1
7.4 years ago by
Istvan Albert ♦♦ 85k
University Park, USA
Istvan Albert ♦♦ 85k wrote:

You can also apply a logarithmic scaling onto the values, this will greatly compress the range.

Hmm, I can try that but I am afraid changing the values in the matrix before doing the clustering will change the clustering in a way I don´t want from the biological point of view...

Content
Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.