使用 downloadHandler 下载 Plotly
Download Plotly using downloadHandler
我在尝试使用 downloadHandler
下载 Plotly 图像时卡住了。我只是想不通如何从临时目录中获取图像...
这是一个示例代码:
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)
此外,我不确定如何选择应下载哪些绘图图像。感谢任何提示和帮助!
信息:
--> 我试过使用 webshot
,但是如果我以任何方式缩放或过滤绘图,不幸的是 webshot 不会镜像它
--> 我没有使用可用的 plotly
面板进行下载,因为它无法使用 IE
1) 安装 webshot
包。
2) 安装 phantom.js
:
library(webshot)
install_phantomjs()
详情见?install_phantomjs
。
3) 现在可以使用plotly
包的export
函数了:
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)
您可以保存为 svg
格式。有关解释,请参阅 ?export
。
OP 已编辑 his/her post 以添加要求:
--> 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 来自文件对象。我会尽量减少代码。
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)
编辑
我是对的。有一个更短更简洁的解决方案:
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);
});
}
')
编辑
要select剧情下载,您可以这样做:
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);
});
}
')
)
)
您应该考虑尝试 webshot2. See my detailed answer 类似情况,而不是使用 webshot。
# Webshot and phantomjs have been previously installed.
library(webshot2)
我在尝试使用 downloadHandler
下载 Plotly 图像时卡住了。我只是想不通如何从临时目录中获取图像...
这是一个示例代码:
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)
此外,我不确定如何选择应下载哪些绘图图像。感谢任何提示和帮助!
信息:
--> 我试过使用 webshot
,但是如果我以任何方式缩放或过滤绘图,不幸的是 webshot 不会镜像它
--> 我没有使用可用的 plotly
面板进行下载,因为它无法使用 IE
1) 安装 webshot
包。
2) 安装 phantom.js
:
library(webshot)
install_phantomjs()
详情见?install_phantomjs
。
3) 现在可以使用plotly
包的export
函数了:
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)
您可以保存为 svg
格式。有关解释,请参阅 ?export
。
OP 已编辑 his/her post 以添加要求:
--> 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 来自文件对象。我会尽量减少代码。
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)
编辑
我是对的。有一个更短更简洁的解决方案:
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);
});
}
')
编辑
要select剧情下载,您可以这样做:
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);
});
}
')
)
)
您应该考虑尝试 webshot2. See my detailed answer 类似情况,而不是使用 webshot。
# Webshot and phantomjs have been previously installed.
library(webshot2)