使用 downloadHandler 下载 Plotly [英] Download Plotly using downloadHandler

查看:77
本文介绍了使用 downloadHandler 下载 Plotly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 downloadHandler 下载 Plotly 图像时卡住了.我只是无法进一步弄清楚如何从临时目录中获取图像...

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...

这是一个示例代码:

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!

信息:

--> 我曾尝试使用 webshot,但是如果我以任何方式缩放或过滤绘图,不幸的是 webshot 不会反映它

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

--> 我没有使用可用的 plotly 面板进行下载,因为它不能使用 IE

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

推荐答案

OP 已编辑他/她的帖子以添加要求:

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

--> 我尝试过使用 webshot,但是如果我以任何方式缩放或过滤绘图,不幸的是 webshot 不会镜像它

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

下面是一个 Javascript 解决方案,它不需要额外的库.我不精通 Javascript,我不确定该方法是最直接的方法:我的印象是此方法从 url 创建一个文件对象,然后从文件对象创建一个 url.我会尽量减少代码.

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);                      
                  });
                  }
                  ')
    )
  )

这篇关于使用 downloadHandler 下载 Plotly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆