I am generating a heatmap in R with lots of rows.
TL;DR how do I get the real size of a plot in R?
df=data.frame(one=1:100,two=101:200,three=201:300)
names=1:100
names=paste0("Cell",names)
rownames(df)=(names)
pheatmap(df,scale="row")
default image fits in window, but we can't read row names.
pheatmap(df,scale="row",cellheight = 10)
changing the cell height lets us read row names but now the image doesn't fit in the window!
In this example i am using pheatmap
, but also run into this stuff with other plot generating packages.
While I've grown to expect frustrating behavior like this from R and by trial and error could make an appropriately size image for the plot, this seems like something that I should be able to get from the program?
Is there a way to get the dimensions of the plot automatically so that I can create correctly size PDF or PNG for it?
The function pheatmap
uses grid graphics to draw its plots, and specifies the size of its elements in "bigpts" where 72 "bigpts" == 1 inch. If you have lots of rows and specify a reasonable row height, this will exceed the plotting window.
Because it is specified as a gtree
, we can actually access the height and width of the components and use them to set the dimensions of our png or pdf.
This function will harvest the total height and width in inches of a plot, returning them in a named list:
get_plot_dims <- function(heat_map)
{
plot_height <- sum(sapply(heat_map$gtable$heights, grid::convertHeight, "in"))
plot_width <- sum(sapply(heat_map$gtable$widths, grid::convertWidth, "in"))
return(list(height = plot_height, width = plot_width))
}
We can use this to specify the dimensions of our plotting device:
my_plot <- pheatmap(df,scale="row", cellheight = 10)
plot_dims <- get_plot_dims(my_plot)
png("plot.png", height = plot_dims$height, width = plot_dims$width, units = "in", res = 72)
my_plot
dev.off()
Which gives the desired plot
Note that this is not a general solution for R plots, but specific to pheatmap
objects.