Search code examples
rggplot2rstudiopngx11

How to save ggrough chart as .png


Say that I am using the R package ggrough (https://xvrdm.github.io/ggrough/). I have this code (taken from that webpage):

library(ggplot2)
library(ggrough)
count(mtcars, carb) %>%
    ggplot(aes(carb, n)) +
    geom_col() + 
    labs(title="Number of cars by carburator count") + 
    theme_grey(base_size = 16) -> p 
options <- list(
    Background=list(roughness=8),
    GeomCol=list(fill_style="zigzag", angle_noise=0.5, fill_weight=2))

I can then create the chart (I am using RStudio):

get_rough_chart(p, options)

However, what code can I use to save it as a .png file? I am trying:

png("ggrough.png")
get_rough_chart(p, options)
dev.off()

I also tried:

x11()
get_rough_chart(p, options)

But this doesn't work either (and even if it did render in the x11 window, I don't know how to then save that as a .png.

What should I do to save the ggrough plot as a .png?


Solution

  • The ggrough plot is an htmlwidget at heart so I do not think typical image saving code will work.

    As mentioned, you can save htmlwidgets to disk via htmlwidgets::saveWidget(rough_chart_object, "rough_chart.html"). This creates an html file with an html canvas element that is drawn on via embedded javascript. As you noticed, webshot::webshot() is not able to capture the image for some reason I too have yet to figure out.

    Because the html file renders correctly in Chrome, I wrote up this RSelenium approach. However, RSelenium can be a pain to get running with all the inter-dependencies, and the image created via this approach may require post-processing. That is, because the plot does not fill the entire canvas element, the image contains a lot of undesirable white space.

    But I will leave this approach here for others to think about.

    library(dplyr)
    library(ggplot2)
    library(ggrough)
    library(RSelenium)
    library(htmlwidgets)
    
    # make ggplot
    count(mtcars, carb) %>%
      ggplot(aes(carb, n)) +
      geom_col() + 
      labs(title="Number of cars by carburator count") + 
      theme_grey(base_size = 16) -> gg_obj
    
    # convert to rough chart
    options <- list(
      Background=list(roughness=8),
      GeomCol=list(fill_style="zigzag", angle_noise=0.5, fill_weight=2))
    
    rough_chart <- get_rough_chart(p = gg_obj, rough_user_options = options)
    
    # save rough chart
    saveWidget(rough_chart, "rough_chart.html")
    
    # start selenium driver
    rd <- remoteDriver(
      remoteServerAddr = "localhost", 
      port = 4444L,
      browserName = "chrome"
    )
    
    rd$open()
    
    # navigate to saved rough chart file
    rd$navigate(paste0("file:///", getwd(), "/rough_chart.html"))
    
    # find canvas element and size
    canvas_element <- rd$findElement("id", "canvas")
    canvas_size <- canvas_element$getElementSize()
    
    # zoom to chart size with padding
    rd$setWindowSize(canvas_size$width + 2 * canvas_size$x, 
                     canvas_size$height + 2 * canvas_size$y)
    
    # save as png
    rd$screenshot(file = "rough_chart.png")
    
    # close chrome
    rd$close()
    

    plot need help