Download Plotly using downloadHandler










2















i got stuck at some point while trying to use downloadHandler to download Plotly images. I just cannot figure out further how to get the image from temp directory...



Here is a sample code:



library(shiny)
library(plotly)
library(rsvg)
library(ggplot2)

d <- data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))

ui <-fluidPage(
title = 'Download Plotly',
sidebarLayout(

sidebarPanel(
helpText(),
downloadButton('download'),
tags$script('
document.getElementById("download").onclick = function()
var plotly_svg = Plotly.Snapshot.toSVG(
document.querySelectorAll(".plotly")[0]
);

Shiny.onInputChange("plotly_svg", plotly_svg);
;
')
),
mainPanel(
plotlyOutput('regPlot'),
plotlyOutput('regPlot2')
)
)
)

server <- function(input, output, session)

output$regPlot <- renderPlotly(
p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
p
)

output$regPlot2 <- renderPlotly(
p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
p
)

observeEvent(input$plotly_svg, priority = 10,
png_gadget <- tempfile(fileext = ".png")
png_gadget <- "out.png"
print(png_gadget)
rsvg_png(charToRaw(input$plotly_svg), png_gadget)
)

output$download <- downloadHandler(
filename = function()
paste(paste("test",Sys.Date(),sep=""), ".png",sep=""),
content = function(file)
temp_dir <- tempdir()
tempImage <- file.path(temp_dir, 'out.png')
file.copy('out.png', tempImage, overwrite = TRUE)
png(file, width = 1200, height = 800, units = "px", pointsize = 12, bg = "white", res = NA)
dev.off()
)


shinyApp(ui = ui, server = server)


Additionally i am not sure how can i choose which of the plotly images should be downloaded. Thanks for any tips and help!



Info:



--> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it



--> i am not using the available plotly panel for download, because it is not working using IE










share|improve this question




























    2















    i got stuck at some point while trying to use downloadHandler to download Plotly images. I just cannot figure out further how to get the image from temp directory...



    Here is a sample code:



    library(shiny)
    library(plotly)
    library(rsvg)
    library(ggplot2)

    d <- data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))

    ui <-fluidPage(
    title = 'Download Plotly',
    sidebarLayout(

    sidebarPanel(
    helpText(),
    downloadButton('download'),
    tags$script('
    document.getElementById("download").onclick = function()
    var plotly_svg = Plotly.Snapshot.toSVG(
    document.querySelectorAll(".plotly")[0]
    );

    Shiny.onInputChange("plotly_svg", plotly_svg);
    ;
    ')
    ),
    mainPanel(
    plotlyOutput('regPlot'),
    plotlyOutput('regPlot2')
    )
    )
    )

    server <- function(input, output, session)

    output$regPlot <- renderPlotly(
    p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
    p
    )

    output$regPlot2 <- renderPlotly(
    p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
    p
    )

    observeEvent(input$plotly_svg, priority = 10,
    png_gadget <- tempfile(fileext = ".png")
    png_gadget <- "out.png"
    print(png_gadget)
    rsvg_png(charToRaw(input$plotly_svg), png_gadget)
    )

    output$download <- downloadHandler(
    filename = function()
    paste(paste("test",Sys.Date(),sep=""), ".png",sep=""),
    content = function(file)
    temp_dir <- tempdir()
    tempImage <- file.path(temp_dir, 'out.png')
    file.copy('out.png', tempImage, overwrite = TRUE)
    png(file, width = 1200, height = 800, units = "px", pointsize = 12, bg = "white", res = NA)
    dev.off()
    )


    shinyApp(ui = ui, server = server)


    Additionally i am not sure how can i choose which of the plotly images should be downloaded. Thanks for any tips and help!



    Info:



    --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it



    --> i am not using the available plotly panel for download, because it is not working using IE










    share|improve this question


























      2












      2








      2


      3






      i got stuck at some point while trying to use downloadHandler to download Plotly images. I just cannot figure out further how to get the image from temp directory...



      Here is a sample code:



      library(shiny)
      library(plotly)
      library(rsvg)
      library(ggplot2)

      d <- data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))

      ui <-fluidPage(
      title = 'Download Plotly',
      sidebarLayout(

      sidebarPanel(
      helpText(),
      downloadButton('download'),
      tags$script('
      document.getElementById("download").onclick = function()
      var plotly_svg = Plotly.Snapshot.toSVG(
      document.querySelectorAll(".plotly")[0]
      );

      Shiny.onInputChange("plotly_svg", plotly_svg);
      ;
      ')
      ),
      mainPanel(
      plotlyOutput('regPlot'),
      plotlyOutput('regPlot2')
      )
      )
      )

      server <- function(input, output, session)

      output$regPlot <- renderPlotly(
      p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
      p
      )

      output$regPlot2 <- renderPlotly(
      p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
      p
      )

      observeEvent(input$plotly_svg, priority = 10,
      png_gadget <- tempfile(fileext = ".png")
      png_gadget <- "out.png"
      print(png_gadget)
      rsvg_png(charToRaw(input$plotly_svg), png_gadget)
      )

      output$download <- downloadHandler(
      filename = function()
      paste(paste("test",Sys.Date(),sep=""), ".png",sep=""),
      content = function(file)
      temp_dir <- tempdir()
      tempImage <- file.path(temp_dir, 'out.png')
      file.copy('out.png', tempImage, overwrite = TRUE)
      png(file, width = 1200, height = 800, units = "px", pointsize = 12, bg = "white", res = NA)
      dev.off()
      )


      shinyApp(ui = ui, server = server)


      Additionally i am not sure how can i choose which of the plotly images should be downloaded. Thanks for any tips and help!



      Info:



      --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it



      --> i am not using the available plotly panel for download, because it is not working using IE










      share|improve this question
















      i got stuck at some point while trying to use downloadHandler to download Plotly images. I just cannot figure out further how to get the image from temp directory...



      Here is a sample code:



      library(shiny)
      library(plotly)
      library(rsvg)
      library(ggplot2)

      d <- data.frame(X1=rnorm(50,mean=50,sd=10),X2=rnorm(50,mean=5,sd=1.5),Y=rnorm(50,mean=200,sd=25))

      ui <-fluidPage(
      title = 'Download Plotly',
      sidebarLayout(

      sidebarPanel(
      helpText(),
      downloadButton('download'),
      tags$script('
      document.getElementById("download").onclick = function()
      var plotly_svg = Plotly.Snapshot.toSVG(
      document.querySelectorAll(".plotly")[0]
      );

      Shiny.onInputChange("plotly_svg", plotly_svg);
      ;
      ')
      ),
      mainPanel(
      plotlyOutput('regPlot'),
      plotlyOutput('regPlot2')
      )
      )
      )

      server <- function(input, output, session)

      output$regPlot <- renderPlotly(
      p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
      p
      )

      output$regPlot2 <- renderPlotly(
      p <- plot_ly(d, x = d$X1, y = d$X2,mode = "markers")
      p
      )

      observeEvent(input$plotly_svg, priority = 10,
      png_gadget <- tempfile(fileext = ".png")
      png_gadget <- "out.png"
      print(png_gadget)
      rsvg_png(charToRaw(input$plotly_svg), png_gadget)
      )

      output$download <- downloadHandler(
      filename = function()
      paste(paste("test",Sys.Date(),sep=""), ".png",sep=""),
      content = function(file)
      temp_dir <- tempdir()
      tempImage <- file.path(temp_dir, 'out.png')
      file.copy('out.png', tempImage, overwrite = TRUE)
      png(file, width = 1200, height = 800, units = "px", pointsize = 12, bg = "white", res = NA)
      dev.off()
      )


      shinyApp(ui = ui, server = server)


      Additionally i am not sure how can i choose which of the plotly images should be downloaded. Thanks for any tips and help!



      Info:



      --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it



      --> i am not using the available plotly panel for download, because it is not working using IE







      r shiny r-plotly






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Feb 8 at 17:17









      Stéphane Laurent

      15.2k75596




      15.2k75596










      asked Nov 15 '18 at 7:24









      Mal_aMal_a

      1,96211333




      1,96211333






















          2 Answers
          2






          active

          oldest

          votes


















          2














          The OP has edited his/her post to add a requirement:




          --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it




          Below is a Javascript solution, which doesn't need additional libraries. I'm not fluent in Javascript and I'm not sure the method is the most direct one: I'm under the impression that this method creates a file object from a url and then it creates a url from the file object. I will try to minimize the code.



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          function download(url, filename, mimeType)
          return (fetch(url)
          .then(function(res)return res.arrayBuffer();)
          .then(function(buf)return new File([buf], filename, type:mimeType);)
          );

          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          download(url, "plot.png", "image/png")
          .then(function(file)
          var a = window.document.createElement("a");
          a.href = window.URL.createObjectURL(new Blob([file], type: "image/png"));
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );
          );

          ')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )



          shinyApp(ui = ui, server = server)


          EDIT



          I was right. There's a shorter and cleaner solution:



           tags$script('
          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')


          EDIT



          To select the plot to download, you can do:



           sidebarLayout(

          sidebarPanel(
          helpText(),
          selectInput("selectplot", "Select plot to download", choices=list("plot1","plot2")),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          document.getElementById("download").onclick = function()
          var plot = $("#selectplot").val();
          if(plot == "plot1")
          var gd = document.getElementById("regPlot");
          else
          var gd = document.getElementById("regPlot2");

          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')
          )
          )





          share|improve this answer




















          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:28











          • Thanks!It works smooth!

            – Mal_a
            Nov 15 '18 at 10:28











          • @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

            – Stéphane Laurent
            Nov 15 '18 at 10:30











          • Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

            – Mal_a
            Nov 15 '18 at 10:32






          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:52


















          1














          1) Install the webshot package.



          2) Install phantom.js:



          library(webshot)
          install_phantomjs()


          See ?install_phantomjs for the details.



          3) Now you can use the export function of the plotly package:



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          downloadButton('download')
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )

          output$download <- downloadHandler(
          filename = function()
          paste0(paste0("test", Sys.Date()), ".png")
          ,
          content = function(file)
          export(regPlot(), file=file)
          )


          shinyApp(ui = ui, server = server)


          You can save to the svg format. See ?export for the explanations.






          share|improve this answer























          • Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

            – Mal_a
            Nov 15 '18 at 8:57











          • @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

            – Stéphane Laurent
            Nov 15 '18 at 9:00











          • i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

            – Mal_a
            Nov 15 '18 at 9:01











          • @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

            – Stéphane Laurent
            Nov 15 '18 at 10:34











          • Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

            – Mal_a
            Nov 15 '18 at 10:37











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53314307%2fdownload-plotly-using-downloadhandler%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          The OP has edited his/her post to add a requirement:




          --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it




          Below is a Javascript solution, which doesn't need additional libraries. I'm not fluent in Javascript and I'm not sure the method is the most direct one: I'm under the impression that this method creates a file object from a url and then it creates a url from the file object. I will try to minimize the code.



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          function download(url, filename, mimeType)
          return (fetch(url)
          .then(function(res)return res.arrayBuffer();)
          .then(function(buf)return new File([buf], filename, type:mimeType);)
          );

          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          download(url, "plot.png", "image/png")
          .then(function(file)
          var a = window.document.createElement("a");
          a.href = window.URL.createObjectURL(new Blob([file], type: "image/png"));
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );
          );

          ')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )



          shinyApp(ui = ui, server = server)


          EDIT



          I was right. There's a shorter and cleaner solution:



           tags$script('
          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')


          EDIT



          To select the plot to download, you can do:



           sidebarLayout(

          sidebarPanel(
          helpText(),
          selectInput("selectplot", "Select plot to download", choices=list("plot1","plot2")),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          document.getElementById("download").onclick = function()
          var plot = $("#selectplot").val();
          if(plot == "plot1")
          var gd = document.getElementById("regPlot");
          else
          var gd = document.getElementById("regPlot2");

          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')
          )
          )





          share|improve this answer




















          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:28











          • Thanks!It works smooth!

            – Mal_a
            Nov 15 '18 at 10:28











          • @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

            – Stéphane Laurent
            Nov 15 '18 at 10:30











          • Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

            – Mal_a
            Nov 15 '18 at 10:32






          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:52















          2














          The OP has edited his/her post to add a requirement:




          --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it




          Below is a Javascript solution, which doesn't need additional libraries. I'm not fluent in Javascript and I'm not sure the method is the most direct one: I'm under the impression that this method creates a file object from a url and then it creates a url from the file object. I will try to minimize the code.



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          function download(url, filename, mimeType)
          return (fetch(url)
          .then(function(res)return res.arrayBuffer();)
          .then(function(buf)return new File([buf], filename, type:mimeType);)
          );

          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          download(url, "plot.png", "image/png")
          .then(function(file)
          var a = window.document.createElement("a");
          a.href = window.URL.createObjectURL(new Blob([file], type: "image/png"));
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );
          );

          ')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )



          shinyApp(ui = ui, server = server)


          EDIT



          I was right. There's a shorter and cleaner solution:



           tags$script('
          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')


          EDIT



          To select the plot to download, you can do:



           sidebarLayout(

          sidebarPanel(
          helpText(),
          selectInput("selectplot", "Select plot to download", choices=list("plot1","plot2")),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          document.getElementById("download").onclick = function()
          var plot = $("#selectplot").val();
          if(plot == "plot1")
          var gd = document.getElementById("regPlot");
          else
          var gd = document.getElementById("regPlot2");

          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')
          )
          )





          share|improve this answer




















          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:28











          • Thanks!It works smooth!

            – Mal_a
            Nov 15 '18 at 10:28











          • @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

            – Stéphane Laurent
            Nov 15 '18 at 10:30











          • Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

            – Mal_a
            Nov 15 '18 at 10:32






          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:52













          2












          2








          2







          The OP has edited his/her post to add a requirement:




          --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it




          Below is a Javascript solution, which doesn't need additional libraries. I'm not fluent in Javascript and I'm not sure the method is the most direct one: I'm under the impression that this method creates a file object from a url and then it creates a url from the file object. I will try to minimize the code.



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          function download(url, filename, mimeType)
          return (fetch(url)
          .then(function(res)return res.arrayBuffer();)
          .then(function(buf)return new File([buf], filename, type:mimeType);)
          );

          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          download(url, "plot.png", "image/png")
          .then(function(file)
          var a = window.document.createElement("a");
          a.href = window.URL.createObjectURL(new Blob([file], type: "image/png"));
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );
          );

          ')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )



          shinyApp(ui = ui, server = server)


          EDIT



          I was right. There's a shorter and cleaner solution:



           tags$script('
          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')


          EDIT



          To select the plot to download, you can do:



           sidebarLayout(

          sidebarPanel(
          helpText(),
          selectInput("selectplot", "Select plot to download", choices=list("plot1","plot2")),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          document.getElementById("download").onclick = function()
          var plot = $("#selectplot").val();
          if(plot == "plot1")
          var gd = document.getElementById("regPlot");
          else
          var gd = document.getElementById("regPlot2");

          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')
          )
          )





          share|improve this answer















          The OP has edited his/her post to add a requirement:




          --> I have tried using webshot, however if I zoom or filter in any way plot, unfortunatelly webshot does not mirror it




          Below is a Javascript solution, which doesn't need additional libraries. I'm not fluent in Javascript and I'm not sure the method is the most direct one: I'm under the impression that this method creates a file object from a url and then it creates a url from the file object. I will try to minimize the code.



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          function download(url, filename, mimeType)
          return (fetch(url)
          .then(function(res)return res.arrayBuffer();)
          .then(function(buf)return new File([buf], filename, type:mimeType);)
          );

          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          download(url, "plot.png", "image/png")
          .then(function(file)
          var a = window.document.createElement("a");
          a.href = window.URL.createObjectURL(new Blob([file], type: "image/png"));
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );
          );

          ')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )



          shinyApp(ui = ui, server = server)


          EDIT



          I was right. There's a shorter and cleaner solution:



           tags$script('
          document.getElementById("download").onclick = function()
          var gd = document.getElementById("regPlot");
          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')


          EDIT



          To select the plot to download, you can do:



           sidebarLayout(

          sidebarPanel(
          helpText(),
          selectInput("selectplot", "Select plot to download", choices=list("plot1","plot2")),
          actionButton('download', "Download")
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2'),
          tags$script('
          document.getElementById("download").onclick = function()
          var plot = $("#selectplot").val();
          if(plot == "plot1")
          var gd = document.getElementById("regPlot");
          else
          var gd = document.getElementById("regPlot2");

          Plotly.Snapshot.toImage(gd, format: "png").once("success", function(url)
          var a = window.document.createElement("a");
          a.href = url;
          a.type = "image/png";
          a.download = "plot.png";
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          );

          ')
          )
          )






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 15 '18 at 10:52

























          answered Nov 15 '18 at 10:20









          Stéphane LaurentStéphane Laurent

          15.2k75596




          15.2k75596







          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:28











          • Thanks!It works smooth!

            – Mal_a
            Nov 15 '18 at 10:28











          • @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

            – Stéphane Laurent
            Nov 15 '18 at 10:30











          • Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

            – Mal_a
            Nov 15 '18 at 10:32






          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:52












          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:28











          • Thanks!It works smooth!

            – Mal_a
            Nov 15 '18 at 10:28











          • @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

            – Stéphane Laurent
            Nov 15 '18 at 10:30











          • Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

            – Mal_a
            Nov 15 '18 at 10:32






          • 1





            @Mal_a See the edit.

            – Stéphane Laurent
            Nov 15 '18 at 10:52







          1




          1





          @Mal_a See the edit.

          – Stéphane Laurent
          Nov 15 '18 at 10:28





          @Mal_a See the edit.

          – Stéphane Laurent
          Nov 15 '18 at 10:28













          Thanks!It works smooth!

          – Mal_a
          Nov 15 '18 at 10:28





          Thanks!It works smooth!

          – Mal_a
          Nov 15 '18 at 10:28













          @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

          – Stéphane Laurent
          Nov 15 '18 at 10:30





          @Mal_a You can also set a width and a height for the plot: format:'png', height:400, width:400

          – Stéphane Laurent
          Nov 15 '18 at 10:30













          Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

          – Mal_a
          Nov 15 '18 at 10:32





          Great! Thanks, i have one more question as you can see i am having there two plots, i am wondering how can i be able to download both of them (depending on maybe selectInput choice)

          – Mal_a
          Nov 15 '18 at 10:32




          1




          1





          @Mal_a See the edit.

          – Stéphane Laurent
          Nov 15 '18 at 10:52





          @Mal_a See the edit.

          – Stéphane Laurent
          Nov 15 '18 at 10:52













          1














          1) Install the webshot package.



          2) Install phantom.js:



          library(webshot)
          install_phantomjs()


          See ?install_phantomjs for the details.



          3) Now you can use the export function of the plotly package:



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          downloadButton('download')
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )

          output$download <- downloadHandler(
          filename = function()
          paste0(paste0("test", Sys.Date()), ".png")
          ,
          content = function(file)
          export(regPlot(), file=file)
          )


          shinyApp(ui = ui, server = server)


          You can save to the svg format. See ?export for the explanations.






          share|improve this answer























          • Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

            – Mal_a
            Nov 15 '18 at 8:57











          • @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

            – Stéphane Laurent
            Nov 15 '18 at 9:00











          • i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

            – Mal_a
            Nov 15 '18 at 9:01











          • @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

            – Stéphane Laurent
            Nov 15 '18 at 10:34











          • Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

            – Mal_a
            Nov 15 '18 at 10:37
















          1














          1) Install the webshot package.



          2) Install phantom.js:



          library(webshot)
          install_phantomjs()


          See ?install_phantomjs for the details.



          3) Now you can use the export function of the plotly package:



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          downloadButton('download')
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )

          output$download <- downloadHandler(
          filename = function()
          paste0(paste0("test", Sys.Date()), ".png")
          ,
          content = function(file)
          export(regPlot(), file=file)
          )


          shinyApp(ui = ui, server = server)


          You can save to the svg format. See ?export for the explanations.






          share|improve this answer























          • Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

            – Mal_a
            Nov 15 '18 at 8:57











          • @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

            – Stéphane Laurent
            Nov 15 '18 at 9:00











          • i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

            – Mal_a
            Nov 15 '18 at 9:01











          • @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

            – Stéphane Laurent
            Nov 15 '18 at 10:34











          • Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

            – Mal_a
            Nov 15 '18 at 10:37














          1












          1








          1







          1) Install the webshot package.



          2) Install phantom.js:



          library(webshot)
          install_phantomjs()


          See ?install_phantomjs for the details.



          3) Now you can use the export function of the plotly package:



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          downloadButton('download')
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )

          output$download <- downloadHandler(
          filename = function()
          paste0(paste0("test", Sys.Date()), ".png")
          ,
          content = function(file)
          export(regPlot(), file=file)
          )


          shinyApp(ui = ui, server = server)


          You can save to the svg format. See ?export for the explanations.






          share|improve this answer













          1) Install the webshot package.



          2) Install phantom.js:



          library(webshot)
          install_phantomjs()


          See ?install_phantomjs for the details.



          3) Now you can use the export function of the plotly package:



          library(shiny)
          library(plotly)

          d <- data.frame(X1 = rnorm(50,mean=50,sd=10),
          X2 = rnorm(50,mean=5,sd=1.5),
          Y = rnorm(50,mean=200,sd=25))

          ui <-fluidPage(
          title = 'Download Plotly',
          sidebarLayout(

          sidebarPanel(
          helpText(),
          downloadButton('download')
          ),

          mainPanel(
          plotlyOutput('regPlot'),
          plotlyOutput('regPlot2')
          )
          )
          )

          server <- function(input, output, session)

          regPlot <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot <- renderPlotly(
          regPlot()
          )

          regPlot2 <- reactive(
          plot_ly(d, x = d$X1, y = d$X2, mode = "markers")
          )
          output$regPlot2 <- renderPlotly(
          regPlot2()
          )

          output$download <- downloadHandler(
          filename = function()
          paste0(paste0("test", Sys.Date()), ".png")
          ,
          content = function(file)
          export(regPlot(), file=file)
          )


          shinyApp(ui = ui, server = server)


          You can save to the svg format. See ?export for the explanations.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 8:54









          Stéphane LaurentStéphane Laurent

          15.2k75596




          15.2k75596












          • Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

            – Mal_a
            Nov 15 '18 at 8:57











          • @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

            – Stéphane Laurent
            Nov 15 '18 at 9:00











          • i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

            – Mal_a
            Nov 15 '18 at 9:01











          • @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

            – Stéphane Laurent
            Nov 15 '18 at 10:34











          • Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

            – Mal_a
            Nov 15 '18 at 10:37


















          • Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

            – Mal_a
            Nov 15 '18 at 8:57











          • @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

            – Stéphane Laurent
            Nov 15 '18 at 9:00











          • i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

            – Mal_a
            Nov 15 '18 at 9:01











          • @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

            – Stéphane Laurent
            Nov 15 '18 at 10:34











          • Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

            – Mal_a
            Nov 15 '18 at 10:37

















          Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

          – Mal_a
          Nov 15 '18 at 8:57





          Thanks for answer! I am aware of webshot, but the problem with it is that if i zoom into the plot (or in any way filter), it does not apper on the exported png...

          – Mal_a
          Nov 15 '18 at 8:57













          @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

          – Stéphane Laurent
          Nov 15 '18 at 9:00





          @Mal_a Hmm ok. Why don't you use the "download plot as png" button of the plot ?

          – Stéphane Laurent
          Nov 15 '18 at 9:00













          i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

          – Mal_a
          Nov 15 '18 at 9:01





          i would actually love to be able to do that! Unfortunatelly at my company our standard web browser is IE, and download plot as png does not work with IE...

          – Mal_a
          Nov 15 '18 at 9:01













          @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

          – Stéphane Laurent
          Nov 15 '18 at 10:34





          @Mal_a Both simultaneously ? Otherwise, do two download buttons, and copy the code for the other plot.

          – Stéphane Laurent
          Nov 15 '18 at 10:34













          Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

          – Mal_a
          Nov 15 '18 at 10:37






          Well i was thinking abpout having some kind of selectInput("selectplot",...choices="plot1","plot2"...) and then use its input for choice of which plot should be downloaded, but i guess i can easily then instead of getElementById("regPlot"), use getElementById(input$selectplot)..i am not very familiar with JavaScript

          – Mal_a
          Nov 15 '18 at 10:37


















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53314307%2fdownload-plotly-using-downloadhandler%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3