Question: How to extract cell positions from pheatmap
gravatar for sunnysean
13 days ago by
sunnysean10 wrote:

Hi, I am trying to add points and lines to some certain cells in pheatmap image. But it is very hard to get their positions by extracting them from pheatmap object. Manually obtaining the positions with locator() or something like this is not a good way, as it cannot handle a bulk of points. Anyone can help me?

R • 82 views
ADD COMMENTlink modified 12 days ago by Kevin Blighe42k • written 13 days ago by sunnysean10
gravatar for Kevin Blighe
12 days ago by
Kevin Blighe42k
Kevin Blighe42k wrote:

I don't think that there is any quick way to do what you want. One way is to use grid functions:

1, create random data

data <- replicate(20, rnorm(50))
rownames(data) <- paste("Gene", c(1:nrow(data)))
colnames(data) <- paste("Sample", c(1:ncol(data)))

2, create col and row metadata

metadata <- data.frame(
      c(rep("case", ncol(data)/2), rep("control", ncol(data)/2)),
      c(rep("cond1", ncol(data)/4), rep("cond2", ncol(data)/4), rep("cond3", ncol(data)/4), rep("cond4", ncol(data)/4)),
colnames(metadata) <- c("casecontrol","condition")

metadata_gene <- data.frame(
      c(rep("Tcell", nrow(data)/2), rep("Bcell", nrow(data)/2)),
colnames(metadata_gene) <- c("Cell")

3, create the heatmap

out <- pheatmap(data, 
      show_rownames=F, cluster_cols=T, cluster_rows=T, scale="row",
      cex=1, clustering_distance_rows="euclidean", cex=1,
      clustering_distance_cols="euclidean", clustering_method="complete", border_color=FALSE,

4, add annotation

Add a vertical line at 8th column

  x = unit(c(8/ncol(data), 8/ncol(data)), "npc"),
  y = c(0.1, 0.9),
  gp = gpar(lty = 2, lwd = 3, col = "black"))

The x and y relate to c(x1, x2) and c(y1, y2), respectively. A useful way to quickly identify regions is to do as I have done for x, i.e.,

  • c(8/ncol(data), 8/ncol(data)), x1 x2 will relate roughly to 8th column
  • c(15/ncol(data), 15/ncol(data)), x1 x2 will relate roughly to 15th column
  • et cetera

Horizontal line at middle, from 1st to 18th column:

  x = unit(c(1/ncol(data), 18/ncol(data)), "npc"),
  y = c(0.5, 0.5),
  gp = gpar(lty = 2, lwd = 3, col = "royalblue"))

add an arrow

  x = unit(c(10/ncol(data), 13/ncol(data)), "npc"),
  y = unit(c(0.6, 0.6), "npc"),
  gp = gpar(fill="black"),
  arrow = arrow(length = unit(0.25, "inches"), ends="last", type="closed"))

add text

  x = unit(c(10/ncol(data)), "npc"),
  y = 0.6,
  just = "top",
  rot = 0,
  gp=gpar(col="black", fontsize=18, face="bold"))


You can look up other grid functions so that you can draw points, et cetera.

Other ways of editing pheatmap objects: A: pheatmap annotation - legend only for columns


ADD COMMENTlink written 12 days ago by Kevin Blighe42k

Thanks for your answer. I am using RStudio, where your codes seems not work very well for unknown reason. Take these codes for example: grid.lines( x = unit(c(8/ncol(data), 8/ncol(data)), "npc"), y = c(0.1, 0.9), gp = gpar(lty = 2, lwd = 3, col = "black")).

The position of added line always change when I resize the plot window in Rstudio. I want to output a pdf picture, but the position of added line is totally wrong for the same reason.

Then, I followed your second suggestion, using grob. a=grid.get('GRID.rect.91') # return all the cells of pheatmap matrix rects a$x; a$y # this gives the coordinates of every cell. grid.point(a$x[1], a$y[1]) # this doesn't draw a point on the up-left cell of pheatmap matrix rects

The coordinates system seems conflicting. Could you give any more suggestion?

ADD REPLYlink written 9 days ago by sunnysean10
Please log in to add an answer.


Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1103 users visited in the last hour