How to draw pheatmap plot to screen and also save to file
Asked Answered
G

5

6

I'm working with the pheatmap package. By default, it draws the plot to the screen. In my case, that means output in a R markdown notebook in R studio. But I also want to save to a file. If I save it to a file, giving it the filename= argument, it doesn't draw to the screen (R notebook). Is there a way to get both things to happen? And more generally, with any plot (ggplot2) where I want to both save and show on the screen?

Glandule answered 27/3, 2017 at 16:17 Comment(0)
S
12

The authors of pheatmap didn't seem to make this super easy. But it's something you are going to need to do in two separate steps. First, we use the sample data from the ?pheatmap help page

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

We can render the plot and save the result with

xx <- pheatmap(test)

Then you can output to this to a file by opening a graphics device and re-drawing the result the way it's done in the main function

save_pheatmap_pdf <- function(x, filename, width=7, height=7) {
   stopifnot(!missing(x))
   stopifnot(!missing(filename))
   pdf(filename, width=width, height=height)
   grid::grid.newpage()
   grid::grid.draw(x$gtable)
   dev.off()
}
save_pheatmap_pdf(xx, "test.pdf")

This package uses the grid library directly and does not use ggplot2 so solutions for that package would be different. The ggsave function makes it easier to save the last drawn plot to a file.

Soso answered 27/3, 2017 at 16:39 Comment(1)
Thanks! This is very useful. Too bad it's kind of convoluted, but I'll take it just the same.Glandule
G
2

FYI, I made a more complex function that includes making the pheatmap and then calling the save_heatmap function from above. I'm posting it here if it is useful to anyone, and also for critiques. I added in a line to save the heatmap image file with the name of the matrix that gives rise to the heatmap. This is helpful for downstream organization of the files.

save_pheatmap <- function(x, filename, width=480, height=960) {
   stopifnot(!missing(x))
   stopifnot(!missing(filename))
   png(filename,width = width, height=height)
   grid::grid.newpage()
   grid::grid.draw(x$gtable)
   dev.off()
}

plot_heatmap <- function(mat,color=NULL, cluster_rows=NULL, cluster_cols=NULL, scale=NULL, 
  cellwidth=NULL, cellheight=NULL,show_colnames=NULL, labels_col=NULL, show_rownames=NULL,
  border_color=NULL,legend=NULL,...){

  #Default Color
  if (is.null(color)){
    color=rev(col.pal)
  }

  #Default cluster
  if (is.null(cluster_rows)){
    cluster_rows=FALSE
  }

  if (is.null(cluster_cols)){
    cluster_cols=FALSE
  }

  #Default sclae
  if(is.null(scale)){
    scale="none"
  }

  #Default cell dims
  if (is.null(cellwidth)){
    cellwidth=12
  }

  if (is.null(cellheight)){
    cellheight=12
  }

  #Default Labels

  if (is.null(show_colnames)){
    show_colnames=TRUE
  }

  if (is.null(labels_col)){
    labels_col=NULL
  }

  if (is.null(show_rownames)){
    show_rownames=FALSE
  }

  #Set border

  if (is.null(border_color)){
    border_color=NA
  }

  #Legend

  if (is.null(legend)){
    legend=FALSE
  }


  temp_hm <- pheatmap(mat,color=color, cluster_rows=cluster_rows, cluster_cols=cluster_cols, scale=scale, 
  cellwidth=cellwidth, cellheight=cellheight,show_colnames=show_colnames, labels_col=labels_col,
  show_rownames=show_rownames,border_color=border_color,legend=legend)

  temp_hm_name <- paste(deparse(substitute(mat)),".png", sep="")

  save_pheatmap(temp_hm, filename=temp_hm_name)

}

Glandule answered 1/4, 2017 at 14:2 Comment(1)
Just as a side note, rather than using all of your if (is.null(...) {...} arguments, you can just put the default argument in the function.Eldoree
C
0

The wplot_save_this() function in the MarkdownReports saves any displayed plot to a .pdf file. Also, all other plotting functions in the package (wbarplot (), whist(), wplot(), etc ) display and save respective as .pdf automatically as well as linking them to a Markdown notebook/ report.

Counterintelligence answered 2/1, 2018 at 10:3 Comment(0)
G
0

I find I can't get the exact same version of the plot with those crafty methods above. For anyone else looking years later, my method is to plot it and then read and display in the notebook

filename = "myhmp.png"    
pheatmap(data, options...  . filename=filename)
magick::image_read(filename) %>% 
     magick::image_scale(.,"1200x1500!") %>% 
     plot
Gymnast answered 19/2, 2023 at 14:26 Comment(0)
P
0

The answer is pretty straightforward, but undocumented, just use ggsave on the output gtable value:

gt <- pheatmap(arguments, filename="image.png")$gtable
ggsave("image.pdf", plot=gt)

If you want, you can leave out the filename from the input arguments in pheatmap, and instead use ggsave twice on the output.

Perspicacious answered 24/7 at 13:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.