我正在尝试下载已经绘制的ggplot
图片而不再重新绘制它。我找到的所有解决方案(例如Save plots made in a shiny app)调用函数在下载图像时再次创建图形。
有解决方法吗?我的图像非常复杂,需要一些时间来创建。
答案 0 :(得分:1)
使用ggplot2::last_plot
功能:
library(shiny)
library(ggplot2)
k <- 0
runApp(list(
ui = fluidPage(
plotOutput("fooplot"),
textOutput("fook"),
downloadButton('foo')
),
server = function(input, output) {
plotInput = function() {
k <<- k + 1
qplot(speed, dist, data = cars)
}
output$fooplot <- renderPlot({
plotInput()
})
output$fook <- renderPrint({
k
})
output$foo = downloadHandler(
filename = 'test.png',
content = function(file) {
device <- function(..., width, height) {
grDevices::png(..., width = width, height = height,
res = 300, units = "in")
}
ggsave("myplot.png", plot = last_plot(), device = device)
})
}
))
原谅使用全局作业,只是为了表明plotInput
没有被调用两次。
答案 1 :(得分:1)
这是旧线程。但是我还需要弄清楚如何避免重新使用Shiny。我的应用程序生成了很多图,并且在last_plot()
中调用ggsave()
并没有太大帮助。
我知道了。确实,由于我们的应用程序中已经有一个图像-我们可以保存该图像。右键单击并在浏览器中选择“保存图像”。 但是,这不是很好-下载按钮和用于下载许多地块的自动化功能会很不错。
要这样做:
library(shinyjs)
,在应用程序的useShinyjs()
部分中调用ui
,然后在runjs()
部分中调用server
); downloadHandler
内运行。因此,我不得不制作actionButton
来运行javascript并在.click()
上模拟一个downloadButton
。我在这里学到了这个技巧:link library(magick)
从URI解码图像并保存。这是该操作的链接:link 这是示例代码:
library(shiny)
library(magick)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
#visibale action button - this button simulates click on hidden download button
actionButton("save_myPlot", "Download", icon = icon("download")),
#hidden download button
downloadButton("save_myPlot_hidden", style = "visibility: hidden;"),
# plot
plotOutput("myPlot")
)
server <- function(input, output, session) {
#get the plot image URI and simulate click on download button
observeEvent(input$save_myPlot, {
shinyjs::runjs(
"
var p_src = document.getElementById('myPlot').childNodes[0].src;
Shiny.setInputValue('plot_src', p_src);
document.getElementById('save_myPlot_hidden').click();
"
)
})
# downaload handler - save the image
output$save_myPlot_hidden <- downloadHandler(
filename = function() {
paste0("plot_", Sys.Date(), ".png") },
content = function(file) {
# get image code from URI
plot_src <- gsub("^data.*base64,", "", input$plot_src)
# decode the image code into the image
plot_image <- image_read(base64_decode(plot_src))
# save the image
image_write(plot_image, file)
})
# plot
output$myPlot <- renderPlot(
plot(rnorm(5), rnorm(5))
)
}
shinyApp(ui = ui, server = server)