R Heatmaps: Non-Linear Mapping Between Colors And Values
3
2
Entering edit mode
10.9 years ago
Irsan ★ 7.8k

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)

Without extremes With extremes

heatmap r • 26k views
ADD COMMENT
9
Entering edit mode
10.9 years ago

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
#now add outliers
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 enter image description here

After enter image description here

ADD COMMENT
0
Entering edit mode

Thanks, thats it!

ADD REPLY
0
Entering edit mode

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

ADD REPLY
1
Entering edit mode
10.9 years ago

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))     
}
ADD COMMENT
0
Entering edit mode

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.

ADD REPLY
1
Entering edit mode
10.9 years ago

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

ADD COMMENT
0
Entering edit mode

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...

ADD REPLY

Login before adding your answer.

Traffic: 1471 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

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

Powered by the version 2.3.6