Save plotly plots to PNG file automatically

1,400 views
Skip to first unread message

dividor

unread,
Mar 10, 2016, 5:45:33 PM3/10/16
to Shiny - Web Framework for R
I am using plotly, but would like to automatically generate an image PNG file for the same plot. 

I am aware that we can call plotly_IMAGE, but this requires a call out to plotly servers which I want to avoid.

I optimistically tried putting my plot_ly call within a renderImage just to test, but it didn't work of course. Below is sample code.

Is there a way to do this please?

thanks!


ui.R

library(shiny)
library(plotly)
library(ggplot2movies)  # Needed for the 'movies' data set

shinyUI(fluidPage(
  titlePanel("Movie Ratings!"),
  sidebarPanel(
    sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 10)
  ),
  mainPanel(
   # plotlyOutput("trendPlot"),
    imageOutput("myImage")
  )
))


server.R

Enter code here...minx <- min(movies$rating)
maxx <- max(movies$rating)

shinyServer(function(input, output) {
  
  output$trendPlot <- renderPlotly({
    # size of the bins depend on the input 'bins'
    size <- (maxx - minx) / input$bins
 
    # a simple histogram of movie ratings
    p <- plot_ly(movies, x = rating, autobinx = F, type = "histogram",
                 xbins = list(start = minx, end = maxx, size = size))
    
    # style the xaxis
    layout(p, xaxis = list(title = "Ratings", range = c(minx, maxx), autorange = F,
                           autotick = F, tick0 = minx, dtick = size))
    
  })
  
  output$myImage <- renderImage({
    # A temp file to save the output.
    # This file will be removed later by renderImage
    outfile <- 'output.png'
    
    # a simple histogram of movie ratings
    size <- (maxx - minx) / input$bins
    p <- plot_ly(movies, x = rating, autobinx = F, type = "histogram",
                 xbins = list(start = minx, end = maxx, size = size))
    # style the xaxis
    layout(p, xaxis = list(title = "Ratings", range = c(minx, maxx), autorange = F,
                           autotick = F, tick0 = minx, dtick = size))
    
    # Return a list containing the filename
    list(src = outfile,
         contentType = 'image/png',
         width = 400,
         height = 300,
         alt = "This is alternate text")
  }, deleteFile = FALSE)
  
  
})







Joe Cheng

unread,
Mar 10, 2016, 8:34:35 PM3/10/16
to dividor, Shiny - Web Framework for R, Yihui Xie
I'm not sure but I've heard rumors that Yihui has the beginnings of a solution to this general problem...? :)

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/b69b9d71-2377-4461-844c-4c813ddfd3f8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yihui Xie

unread,
Mar 11, 2016, 12:03:43 AM3/11/16
to Joe Cheng, dividor, Shiny - Web Framework for R
Right. The webshot package makes this easy: https://github.com/wch/webshot

Here is a quick function that I wrote without any testing (I guess it
depends on the Github version of plotly since I'm using as.widget()
there):

#' @param x a plotly object
screenshot_plotly = function(x, file = 'webshot.png', ...) {
file2 = normalizePath(file, mustWork = FALSE)
d = tempfile()
dir.create(d)
owd = setwd(d)
on.exit({
setwd(owd)
unlink(d, recursive = TRUE)
}, add = TRUE)
htmlwidgets::saveWidget(plotly::as.widget(x), 'index.html', FALSE)
file.copy(webshot::webshot('index.html', ...), file2)
file
}

It returns the path of a screenshot of the plotly object, which I
believe you can pass as the image path to renderImage().

Regards,
Yihui

dividor

unread,
Mar 11, 2016, 9:06:14 AM3/11/16
to Shiny - Web Framework for R
This seems very exciting!

Unfortunately though, my installation of Plotly gives me the error:

Error in : 'as.widget' is not an exported object from 'namespace:plotly'

Searching around on the web, I found this post which mentions downloading a dev version of plotly with ...

devtools::install_github("ropensci/plotly"

(having unloaded plotly first and restarted my session to bypass some namespace errors)

I then got a warning from webshot, telling me to install phantonjs by calling ..

webshot::install_phantomjs()

After all that, it worked perfectly!

My last question is though please - will as.widget be part of the standard plotly install at some point?

Thanks,
Matt

Yihui Xie

unread,
Mar 11, 2016, 1:58:19 PM3/11/16
to dividor, Shiny - Web Framework for R
Yeah I did point out that as.widget() might require the Github version
of plotly, and you need to ask plotly developers when as.widget() will
be available in a CRAN release.

Regards,
Yihui
> --
> You received this message because you are subscribed to the Google Groups
> "Shiny - Web Framework for R" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to shiny-discus...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/shiny-discuss/503e4cec-e8cd-4c3a-a364-faebcdbd3acb%40googlegroups.com.

uap uap

unread,
Mar 11, 2016, 2:19:35 PM3/11/16
to Yihui Xie, Shiny - Web Framework for R
Ah, sorry I missed that part.

Thanks very much Yihui, this is an awesome feature.
Reply all
Reply to author
Forward
0 new messages