How to extract cell positions from pheatmap
1
1
Entering edit mode
5.0 years ago
sunnysean ▴ 20

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 • 2.2k views
ADD COMMENT
2
Entering edit mode
5.0 years ago

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)),
      row.names=colnames(data))
colnames(metadata) <- c("casecontrol","condition")

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

3, create the heatmap

require(pheatmap)
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,
      annotation_col=metadata,
      annotation_row=metadata_gene)

4, add annotation

Add a vertical line at 8th column

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

grid.lines(
  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

grid.lines(
  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

grid.text(
  bquote(Key~cell),
  x = unit(c(10/ncol(data)), "npc"),
  y = 0.6,
  just = "top",
  rot = 0,
  gp=gpar(col="black", fontsize=18, face="bold"))

f

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

Kevin

ADD COMMENT
0
Entering edit mode

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.

grid.ls(grid.force()) 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 REPLY

Login before adding your answer.

Traffic: 3790 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