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"))
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
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?