Shiny中通过downloadHandler导出dygraph图表至PDF失败求助
Shiny中导出dygraph与ggplot混合PDF的解决方案
问题根源
gridExtra::grid.arrange 仅支持处理基于grid绘图系统的静态图形对象(如ggplot2、base R生成的静态图),dygraph属于交互式HTML组件,不属于grid可识别的图形类型,无法直接传入进行排版导出。
解决方案核心逻辑
先将dygraph渲染为静态图片,再转换为grid可识别的对象,即可与ggplot对象合并排版导出为PDF。
依赖安装
先安装所需依赖包:
install.packages(c("ggplot2", "webshot2", "magick", "grid"))
完整可运行修改代码
library(shiny) library(dygraphs) library(htmltools) library(gridExtra) library(ggplot2) library(webshot2) library(magick) library(grid) ui <- navbarPage( tabPanel(title = "Download", downloadButton("downloadcharts1"), downloadButton("downloadcharts2"), downloadButton("downloadcharts") ) ) server <- function(input, output, session){ vals <- reactiveValues(p1=NULL, p2=NULL) temperature <- ts(frequency = 12, start = c(1980, 1), data = c(7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6)) rainfall <- ts(frequency = 12, start = c(1980, 1), data = c(49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4)) data <- as.data.frame(cbind(temperature, rainfall)) g <- ggplot(data = data, aes(x=temperature, y=rainfall)) + geom_point() vals$p1 <- g # create a list of dygraphs objects dy_graph <- list( dygraphs::dygraph(temperature, group="temp_rain", main="temperature"), dygraphs::dygraph(rainfall, group="temp_rain", main="rainfall") ) dy_graph<- htmltools::browsable(htmltools::tagList(dy_graph)) vals$p2 <- dy_graph output$downloadcharts1 <- downloadHandler( filename = function(){"chart1.pdf"}, content = function(file){ pdf(file, onefile=TRUE) grid.arrange(vals$p1) dev.off() } ) output$downloadcharts2 <- downloadHandler( filename = function(){"chart2.pdf"}, content = function(file){ # 创建临时文件存储中间产物 tmp_html <- tempfile(fileext = ".html") tmp_png <- tempfile(fileext = ".png") # 保存dygraph为静态HTML save_html(vals$p2, tmp_html) # HTML转静态PNG,zoom参数控制导出清晰度,数值越大越清晰 webshot(tmp_html, file = tmp_png, zoom = 2) # PNG转grid可识别的grob对象 dy_grob <- rasterGrob(image_read(tmp_png)) # 导出PDF pdf(file, onefile=TRUE) grid.arrange(dy_grob) dev.off() # 清理临时文件 unlink(c(tmp_html, tmp_png)) } ) output$downloadcharts <- downloadHandler( filename = function(){"charts1&2.pdf"}, content = function(file){ tmp_html <- tempfile(fileext = ".html") tmp_png <- tempfile(fileext = ".png") save_html(vals$p2, tmp_html) webshot(tmp_html, file = tmp_png, zoom = 2) dy_grob <- rasterGrob(image_read(tmp_png)) pdf(file, onefile=TRUE) # 按两行排版两个图表,可自行调整ncol/nrow参数修改布局 grid.arrange(vals$p1, dy_grob, nrow = 2) dev.off() unlink(c(tmp_html, tmp_png)) } ) } runApp(list(ui=ui, server=server), launch.browser=TRUE)
内容的提问来源于stack exchange,提问作者K.RAC
相关产品推荐
相关产品推荐

