Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highlight cells in heatmap

I am currently trying to set up a heatmap of a matrix and highlight specific cells, based on two other matrices.

An example:

> SOI
         NAP_G021 NAP_G033  NAP_G039 NAP_G120  NAP_G122
2315101  59.69418 27.26002  69.94698 35.22521  38.63995
2315102 104.15294 76.70379 114.72999 97.35930  79.46014
2315104 164.32822 61.83898 140.99388 63.25482 105.48041
2315105  32.15792 21.03730  26.89965 36.25943  40.46321
2315103  74.67434 82.49875 133.89709 93.17211  35.53019

> above150

         NAP_G021 NAP_G033  NAP_G039 NAP_G120  NAP_G122
2315101  0 0 0 0 0
2315102  0 0 0 0 0
2315104  1 0 0 0 0
2315105  0 0 0 0 0
2315103  0 0 0 0 0

> below30

         NAP_G021 NAP_G033  NAP_G039 NAP_G120  NAP_G122
2315101  0 1 0 0 0
2315102  0 0 0 0 0
2315104  0 0 0 0 0
2315105  0 1 1 0 0
2315103  0 0 0 0 0

Now I create a normal heatmap:

heatmap(t(SOI), Rowv = NA, Colv = NA)

Now what I want to do is highlight the cells, that have a 1 in above150 with a frame of one colour (e.g. blue), whilst the cells with a 1 in below30 should get a red frame. Of couse all matrices are equal sized as they are related. I know that I can add things to the heatmap after processing via add.expr, but so far I just managed to create full ablines that span the whole heatmap => not what I'm looking for.

If anybody has any suggestions I would be delighted.

like image 437
bontus Avatar asked Jan 18 '23 09:01

bontus


1 Answers

When add.expr is called the plot is set so that the centre of the cells is at unit integer values. Try add.expr=points(1:5,1:5) to see. Now all you need to do is write a function that draws boxes (help(rect)) with the colours you need, at the half-integer coordinates.

Try this:

set.seed(310366)

nx=5
ny=6
SOI=matrix(rnorm(nx*ny,100,50),nx,ny)

colnames(SOI)=paste("NAP_G0",sort(as.integer(runif(ny,10,99))),sep="")
rownames(SOI)=sample(2315101:(2315101+nx-1))
above150 = SOI>150
below30=SOI<30

makeRects <- function(tfMat,border){
  cAbove = expand.grid(1:nx,1:ny)[tfMat,]
  xl=cAbove[,1]-0.49
  yb=cAbove[,2]-0.49
  xr=cAbove[,1]+0.49
  yt=cAbove[,2]+0.49
  rect(xl,yb,xr,yt,border=border,lwd=3)
}

heatmap(t(SOI),Rowv = NA, Colv=NA, add.expr = {
 makeRects(above150,"red");makeRects(below30,"blue")})
like image 187
Spacedman Avatar answered Jan 24 '23 20:01

Spacedman