1

I have this data in a txt file (fruits2612e.txt)

"people","1","2","3","4","5","6","7","8","9","10","11","12"
"Ej1",0,0,0,0,0,0,0,0,0,0,0,0
"Ej2",0,0,1,1,1,1,1,1,0,0,0,0
"Ej3",0,0,0,0,0,0,1,0,0,0,0,0
"Ej4",0,1,1,1,0,0,1,1,0,0,0,1
"Ej5",1,1,1,1,1,1,1,1,0,0,0,1
"Ej6",1,1,1,1,0,1,1,1,0,0,1,1
"Ej7",1,1,1,1,1,1,1,1,0,0,0,0
"Ej8",0,0,0,1,1,1,0,0,0,0,0,0
"Ej9",0,0,1,1,1,1,1,1,0,0,0,0
"Ej10",0,0,0,1,1,1,1,0,0,0,0,0
"Ej11",0,0,0,0,1,0,0,0,0,1,1,0
"Ej12",0,0,1,1,1,0,0,0,0,1,1,1
"Ej13",0,1,1,1,0,0,0,1,1,1,1,1
"Ej14",1,1,0,0,0,0,0,1,1,1,0,1
"Ej15",0,0,0,0,0,0,0,1,1,1,1,1
"Ej16",0,0,0,0,0,0,0,1,1,1,1,1

I built the heatmap (without the black rectangle) using this code

library(reshape2)
library(ggplot2)
library(scales)
library(plyr)
data <- read.csv("fruits2612e.txt", head=TRUE, sep=",")
data$people <- factor(data$people,levels=rev(data$people))
data.m = melt(data)
#data.m <- ddply(data.m, .(variable), transform, rescale = rescale(value))
data.m[,"rescale"]<-rescale(data.m[,"value"],to=c(0,1))
fewer.labels <- c("Ej16","Ej15","Ej14","Ej13","Ej12","Ej11","Ej10","Ej9","Ej8","Ej7","Ej6","Ej5","Ej4","Ej3","Ej2","Ej1")
p <- ggplot(data.m, aes(variable, people)) +
     geom_tile(aes(fill = rescale), colour = "white") +
     scale_y_discrete(labels=fewer.labels) +
     scale_fill_gradient(low = "red", high = "green") +
     theme(axis.text=element_text(size=8))

Now I'm trying to add the black rectangle to the heatmap, but can't find out how, the coordinates are

maxR<-c(topLeftx,topLefty,botRightX,botRightY)
[1] 5 1 7 8

enter image description here

user3437823
  • 351
  • 2
  • 14
  • You should look at the `annotate` function and investigate whether `geom='rect'` provides a solution. – IRTFM Dec 26 '14 at 17:44
  • This may help: http://stackoverflow.com/questions/22024641/how-to-add-bounding-box-to-a-specific-area-in-ggplot2-heatmap – KFB Dec 26 '14 at 17:56

2 Answers2

4

Following my own advice, I searched SO for "annotate geom rect" and found one hit: Draw multiple squares with ggplot

maxR<-c(topLeftx=5,topLefty=1,botRightX=7,botRightY=8)
 p +  annotate(geom='rect', xmin= maxR['botRightX'], ymin= maxR['botRightY'],
                            xmax=maxR['topLeftx'], ymax=  maxR['topLefty'], 
                fill="transparent", col="black", lwd=3)

So apparently we have different notions about how to specify the indices of a rectangle but you should be able to take it from here.

enter image description here

Community
  • 1
  • 1
IRTFM
  • 258,963
  • 21
  • 364
  • 487
3

ggplot manipulates factors internally using their codes, which are accessible using, e.g. as.integer(data.m$people), etc. The corners of the tiles are the codes +/- 0.5. So, assuming you really are using factors for both the x- and y-direction, then this will draw the box you want

maxR     <-c(topLeftx=5,topLefty=1,botRightX=7,botRightY=8)
sub.data <- with(data.m,
                 with(as.list(maxR),
                      data.m[people %in% paste0("Ej",topLeftx:botRightX) 
                             & variable %in% paste0("X",topLefty:botRightY),]))

p+with(sub.data,annotate(geom="rect", fill="transparent",color="black", size=1.5,
           xmin=min(as.integer(variable))-0.5,ymin=min(as.integer(people))-0.5,
           xmax=max(as.integer(variable))+0.5,ymax=max(as.integer(people))+0.5))

The tortured code at the beginning is needed because of the bizarre way you've chosen to specify the corners of the box.

jlhoward
  • 58,004
  • 7
  • 97
  • 140