Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put column names on top of heatmap.2 [duplicate]

Tags:

r

layout

heatmap

I am very close to the heatmap I want, but I have been struggling for several days to figure out the headings problem. I want angled headings (such as 45 or 50 degrees) at the top of each column. I have already suppressed the dendrograms (for both columns and rows), and used the first column of my matrix (depth) as labels for the rows.

From my many, many searches on this issue, I see that mtext won't help me because the text cannot be rotated in mtext. Then I thought I could do it with text, but the column labels get overwritten onto the heatmap itself; they "disappear" (get covered) when the words reach the edge of the heatmap layout space. So I examined the layout used by heatmap (thanks very much to @Ian Sudbery), and it occurred to me that what I really need is a dedicated space in the layout for my column headings. I can allocate that space using the layout function, and I have done so in the code below. But I think the next step may involve getting inside the heatmap.2 code. Heatmap.2 calls four plots (two of which I have suppressed, the dendrograms). How do I make it call a fifth plot? And if that is possible, how do I tell it that I want to use text as my fifth "plot", where the text is my column headings, rotated 50deg?

Thanks very much for any ideas. Please forgive the clumsy way I've provided sample data in the code below; I am new to R and generally do not know the most elegant way to do most things.

par(oma=c(0.5,0.5,.5,0.5))  # outer margins of whole figure

lmat = rbind(c(3,5,5),c(2,1,1),c(0,4,0))
lwid = c(.08,.9, .1)
lhei = c(1,4,1.5)

Depth<-c("0m","20m","40m","60m","80m","100m")
Sept2008<-c(3,6,8,10,15,16)
March2010<-c(10,12,11,13,12,11)
Sept2010<-c(5,6,NA,8,11,13)
March2011<-c(4,6,10,NA,14,14)
Sept2011<-c(2,5,3,9,16,12)

heatmap_frame=data.frame(Depth=Depth,Sept2008=Sept2008,March2010=March2010,Sept2010=Sept2010, March2011=March2011, Sept2011=Sept2011)
row.names(heatmap_frame)<-heatmap_frame$Depth
heatmap_frame<-heatmap_frame[,-1]
heatmap_matrix <- as.matrix(heatmap_frame)

labCol=c("Sept 2008","March 2010","Sept 2010","March 2011","Sept 2011")
cexCol=1.1

heatmap <- heatmap.2(heatmap_matrix, dendrogram="none", trace="none",Rowv=NA, Colv=NA, 
                 col = brewer.pal(9,"Blues"), scale="none", margins=c(2,5),labCol="",
                 lmat=lmat, lwid=lwid,lhei=lhei, density.info="none",key=TRUE)

# want to plot a fifth area, to use for col labels
# don't know how to pass a text line to the heatmap.2/layout/matrix to print as my fifth plot

mtext("Use for main title", side=3,outer=F,line=2.75, font=2, cex=1.25)

# testing the text function; did not work as desired
#text(x=1, y=1, labels="Label_1",xpd=T)
text(x=c(0,.2,.4,.6,.8), y=0.95, pos=3, srt=50, labels=labCol,xpd=T, cex=1)
like image 726
user2487639 Avatar asked Nov 22 '22 20:11

user2487639


1 Answers

Here's a hack that doesn't involve pulling apart the convoluted code of heatmap.2:

  pos2 <- locator() #will return plotting coordinates after doing this:
  # Shift focus to the graphics window by clicking on an edge 
  # Left-Click once where you want the first label to be centered
  # Left-click again on the point where you want the last label centered
  # Right-Click, then return focus to the console session window

 pos2 <- structure(list(x = c(0.27149971320082, 0.858971646016485), 
                        y = c(0.861365598392473, 0.857450478257082)),
                       .Names = c("x", "y"))

  text(x=seq(pos2$x[1], pos2$x[2], len=5), y=rep(pos2$y[1],5)  ,
       srt=50, xpd=TRUE, adj = 0,
       labels=c("Sept 2008","March 2010","Sept 2010",
                "March 2011","Sept 2011") )

I don't know if you actually need the xpd in there, since it appears that after heatmap.2 is finished it returns the window to its native coordinates: [0,1]x[0,1]

enter image description here

like image 151
IRTFM Avatar answered Dec 10 '22 13:12

IRTFM