如何让Shiny renderPlot输出的流程地图显示在浏览器而非RStudio Viewer窗格
核心问题定位
这个现象和Shiny本身的渲染路径无关,根源是processmapR包的process_map()函数的默认输出机制:
- 该函数调用后会直接触发底层DiagrammeR引擎,把生成的流程地图作为独立HTML交互图推送到RStudio Viewer窗格展示,并不会把可被
renderPlot()捕获的静态图形对象作为返回值传递出来 renderPlot()只能抓取当前R会话中直接输出到默认绘图设备的静态位图/ggplot对象,自然拿不到被推去Viewer的外部渲染结果,最终表现就是Shiny页面的plotOutput区域空白,图形单独出现在RStudio Viewer里。
方案一:交互图渲染(体验最优,推荐)
流程地图本身是带节点交互的有向网络图,强制转成静态图会丢失缩放、悬浮查看详情的体验,直接适配DiagrammeR的原生Shiny组件是最顺畅的方式,修改点非常少:
- 加载依赖包
DiagrammeR(processmapR已内置该依赖,无需额外安装) - 把UI中原有的
plotOutput("plot1")替换为DiagrammeR专属的输出组件,配置好宽高 - 把服务端中原有的
renderPlot()替换为对应的renderDiagrammeR(),直接传入process_map()的返回值即可
修正后的完整可运行代码:
library(shiny) library(bupaR) library(processmapR) library(DiagrammeR) ui <- fluidPage( tags$h1("Process Mining"), tags$p("The purpose of this application is to show the Process Map output"), fluidRow( selectInput("pm_type","Process Mining Type", c("absolute","relative")) ), fluidRow( # 替换为DiagrammeR输出组件 DiagrammeROutput("plot1", width = "100%", height = "600px") ) ) server <- function(input, output) { selectedData <- reactive({input$pm_type}) # 替换为DiagrammeR渲染方法 output$plot1 <- renderDiagrammeR({ patients %>% process_map(type = frequency(selectedData())) }) } shinyApp(ui = ui, server = server)
修改后运行,流程地图会直接嵌入浏览器端的Shiny页面,不会跳转到RStudio Viewer,还支持节点缩放、点击查看属性的原生交互。
方案二:强制转静态图适配原有renderPlot逻辑
如果你需要保留静态位图的展示形式,不使用交互组件,可以通过两步操作让图形被renderPlot()捕获:
- 调用
process_map()时关闭自动推送到Viewer的逻辑,把图形对象直接捕获为变量 - 借助格式转换工具把DiagrammeR对象转为可被R基础绘图设备识别的栅格图,输出到当前绘图面板
对应代码片段:
# 需提前安装依赖:DiagrammeRsvg、magick output$plot1 <- renderPlot({ # 关闭自动渲染到Viewer的逻辑,仅捕获图形对象 graph_obj <- patients %>% process_map(type = frequency(selectedData()), render = FALSE) # 转换为栅格图后输出到当前plot设备 DiagrammeRsvg::export_svg(graph_obj) %>% charToRaw() %>% magick::image_read() %>% plot() })
避坑提醒:不要尝试用
print()包裹process_map()的结果来解决问题——print触发的还是原函数自动推送Viewer的逻辑,根本不会把图形捕获到当前绘图设备。
内容的提问来源于stack exchange,提问作者bernardojaccoud
相关产品推荐
相关产品推荐

