how to plot multi pheatmap into one figure
2
4
Entering edit mode
9.2 years ago
Zhilong Jia ★ 2.2k

I'd want to combine 3 pheatmap into 1 figure. Here is the test code. it seems mfrow parameter does not work for it.

test = matrix(rnorm(200), 20, 10)
test[1:10, seq(1, 10, 2)] = test[1:10, seq(1, 10, 2)] + 3
test[11:20, seq(2, 10, 2)] = test[11:20, seq(2, 10, 2)] + 2
test[15:20, seq(2, 10, 2)] = test[15:20, seq(2, 10, 2)] + 4
colnames(test) = paste("Test", 1:10, sep = "")
rownames(test) = paste("Gene", 1:20, sep = "")

par(mfrow=c(1,2))
pheatmap(test)
pheatmap(test, kmeans_k = 2)
pheatmap(test, kmeans_k = 3)
pheatmap plotting par • 26k views
ADD COMMENT
1
Entering edit mode

Stuff like this is why I had to write my own heatmap generating code (calls image()). I use layout() to set up multi-heatmap figures. It's pretty ugly.

ADD REPLY
1
Entering edit mode

There's a little better of a description here about how to use layout() and image(). Multi-Panel Heatmaps In R

ADD REPLY
0
Entering edit mode

Normally one just uses Adobe Illustrator or Inkscape to make the final figures. While you certainly can try to arrange everything in R, that's really not its forte.

ADD REPLY
0
Entering edit mode

@Devon, Thanks. The Inkscape or others need plot this kind of figure manually but not automatically. That's the point.

ADD REPLY
3
Entering edit mode
9.2 years ago

If it's just for the one figure, I'd do it manually in Inkscape. However, for high throughput figure production, I would export individual images from R and script the final figure assembly from the components, for example using ImageMagick. You could also write an SVG file directly (for example with the perl module SVG) or by scripting Inkscape.

ADD COMMENT
1
Entering edit mode

why R can not do it ? it's strange. It usually works for other kind of plotting. I prefer using only one language if possible.

ADD REPLY
1
Entering edit mode

I am sure R can do it (have you tried ggplot2 ?) but it's likely unwieldy and not intuitive, unless of course, one is an R aficionado :) I find that R can generate simple plots quite easily but when it comes to getting to publication-quality figures (at least for biology journals), it's quickly getting more complicated. In line with the idea of assembling the components produced separately, you can output SVG files in R with the svg function then, since SVG is XML, you could also edit/combine these files in R.

ADD REPLY
1
Entering edit mode

Agreed, in this case, one would need to directly modify the pheatmap source code. pheatmap directly specifies viewports to draw things in. I don't know enough about the internals of R graphics production, but I imagine that that would override anything set via users.

Sometimes R with a bit of external scripting really is the simplest route.

ADD REPLY
0
Entering edit mode

A lot of heatmap functions use layout() and image() internally, so some of the things you specify via par() will be overridden. This is at least the case for heatmap.2() in the gplots library.

ADD REPLY
15
Entering edit mode
6.4 years ago
bitpir ▴ 240

Hi all, I know my answer is ~3years too late but I just want to put it out there and hopefully people will find this useful in the future. I found the answer here

Basically, user hrbrmstr mentioned that "The manual page for pheatmap() clearly states in the Values section that it returns a list of components, but it fails to mention component #4, which is the gtable of the plot. You have to index it specifically since it's not going to trigger R's print method lookup/execution for that object inside the function call."

For my case, I did the following:

items=unique(ra_items$column)
plot_list=list()
for (a in items){
x=pheatmap(as.matrix(data),
             cluster_rows = F,
             fontsize = 14,
             main = a)
  plot_list[[a]] = x[[4]]     ##to save each plot into a list. note the [[4]]
}
g<-do.call(grid.arrange,plot_list)
ggsave("g.pdf",g)
ADD COMMENT
3
Entering edit mode

Instead of grid.arrange with do.call, you could also use arrangeGrob. arrangeGrob gives you the chance to specify the layout (e.g. number of rows and columns for the combined plots.

g <- grid.arrange(arrangeGrob(grobs= plot_list,ncol=2))
ADD REPLY
0
Entering edit mode

You can do that with do.call as well

do.call("grid.arrange", c(plot_list, ncol=2))

Also, rather than using a for cycle, I would use lapply here.

ADD REPLY
0
Entering edit mode

Thank you for posting the answer. I can across it today, and it was very helpful for me.

ADD REPLY
0
Entering edit mode

Thanks for this. I could not use grob, but your comment and the solution here helped me:

p1=pheatmap(...)
p2=pheatmap(...)
plot_list=list()
plot_list[['p1']]=p1[[4]]
plot_list[['p2']]=p2[[4]]

grid.arrange(grobs=plot_list, ncol=2)
ADD REPLY

Login before adding your answer.

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