gt icon indicating copy to clipboard operation
gt copied to clipboard

Convert gt to grob for cowplot + patchwork

Open jthomasmock opened this issue 3 years ago • 3 comments

Prework

Proposal

In some situations it would be helpful to add a table into the layout of some graphics. While this is possible in RMarkdown/Quarto/HTML/etc, some users prefer patchwork or cowplot when aggregating their plots for other tools.

This would add a dependency for grid (already there from ggplot2) and png.

This is related to https://github.com/rstudio/gt/issues/420 and https://github.com/rstudio/gt/issues/180 - but per Rich, opening as a new issue/FR.

library(patchwork)
library(ggplot2)
library(cowplot)
library(gt)

gt_tab <- head(mtcars) |> 
  gt()

test_plot <- mtcars |> 
  ggplot(aes(x = disp, y = mpg)) +
  geom_point() +
  labs(
    alt = "a plot with text"
  )

gt_grob <- function(gt_object, ...){
  
  out_name <- file.path(
    tempfile(pattern = "file", tmpdir = tempdir(), fileext = ".png")
  )
  
  gtsave(gt_object, out_name, ...)
  
  in_png <- png::readPNG(out_name)
  
  on.exit(file.remove(out_name), add=TRUE)
  
  grid::rasterGrob(in_png)
  
}

gt_plot <- gt_grob(gt_tab)

combo_plot <- test_plot +
  wrap_elements(gt_plot)

cow_plot <- plot_grid(test_plot, gt_plot)

ggsave("patchwork.png", combo_plot, height = 3.5, width = 10)
ggsave("cowplot.png", cow_plot, height = 3.5, width = 10)
### Patchwork works
knitr::include_graphics("patchwork.png")


### Cowplot works
knitr::include_graphics("cowplot.png")

Created on 2022-06-14 by the reprex package (v2.0.1)

jthomasmock avatar Jun 14 '22 18:06 jthomasmock

Out of curiosity, would it be "better" to directly construct a grob rather than round about generating an html->png->raster?

thebioengineer avatar Jul 13 '22 03:07 thebioengineer

Out of curiosity, would it be "better" to directly construct a grob rather than round about generating an html->png->raster?

Likely yes - I just wasn't sure about the path of HTML -> grob. Given that there are powerful tools like RMarkdown/Quarto for arranging mixed content I didn't want to spend too much dev time on building a generic HTML renderer to a grob. The plot -> image -> grob is honestly, a bit of a hack but easy to accomplish.

I'm aware of gridExtra::tableGrob but it seemed both limited and complex given the conversion to literal graphical elements.

https://github.com/baptiste/gridExtra/blob/master/R/tableGrob.r

There's also sinab::html_grob() but it's also very limited in scope and not on CRAN.

https://github.com/clauswilke/sinab/blob/master/R/html_grob.R

jthomasmock avatar Jul 13 '22 03:07 jthomasmock

I poked a bit at using grobs and gtable(which supports gridExtra::tableGrob), and overall it wasn't too difficult. I am still reading and learning how gtable works, but since ggplot2 is based on it too, there could then be some more advanced things you could do with it as a true grob than a rasterized png.

@rich-iannone - if this is of interest to you, I can push the branch to my fork for you to take a look. right now its all just local. It would take a little doing to make it have all the features of html, and add it to handle the images, but 🤷 , probably not overly difficult to get it to a rudimentary level

thebioengineer avatar Jul 21 '22 22:07 thebioengineer