如何将RStudio生成的2个ggplot图表嵌入RShiny仪表盘
RShiny仪表盘嵌入双ggplot图表及PDF插入方案
我帮你整理好了无需用户交互、可自动更新的完整Shiny仪表盘代码,同时解答你关于将ggplot保存为PDF后插入仪表盘的疑问:
一、完整可运行的Shiny仪表盘代码
这份代码会自动加载你的数据、生成两个ggplot图表,并在基础Shinydashboard中上下排列展示,无需任何用户操作就能直接运行:
# 加载所有必需的包 library(shinydashboard) library(shiny) library(readr) library(dplyr) library(ggplot2) library(scales) library(tidyverse) library(lubridate) library(tidyr) # ---------------------- 数据处理部分 ---------------------- # 设置工作目录(请替换为你的文件路径) setwd("/Users/k/Desktop/COVID") # 处理第一个图表的数据:患者输血趋势 o2outcomes <- read.csv(file="patients_transfused.csv", stringsAsFactors = FALSE) # 移除全空或全NA的行 o2outcomes <- o2outcomes[!apply(is.na(o2outcomes) | o2outcomes == "", 1, all),] # 重命名日期列 names(o2outcomes)[10] <- "transfusion_date" # 转换日期格式 o2outcomes$transfusion_date <- parse_date_time(o2outcomes$transfusion_date, orders = "%m/%d/%y %H%M") # 按日期排序 o2outcomes <- o2outcomes[order(o2outcomes$transfusion_date),] # 创建累计患者ID o2outcomes$ID <- seq_len(nrow(o2outcomes)) # 处理第二个图表的数据:患者呼吸支持趋势 cols <- c("AmbientAir"="lightblue","LowFlow"="blue","HighFlow"="orange","NIPPV"="purple","MechanicalVentilation"="red","ECMO"="black") Figure <- read.csv("Figure.csv", header=TRUE) Figure_Event <- read.csv("Figure_Event.csv", header=TRUE) # 筛选事件数据 Figure_Event <- Figure_Event %>% filter(Event %in% c("Discharged", "Death") & Patient < 26) # ---------------------- Shiny仪表盘部分 ---------------------- ui <- dashboardPage( dashboardHeader(title = "Plasma Therapy Dashboard"), dashboardSidebar(disable = TRUE), # 禁用侧边栏,因为无需交互 dashboardBody( # 上下排列两个图表,每个占满整行 fluidRow( box(plotOutput("plot1", height = 350), width = 12) ), fluidRow( box(plotOutput("plot2", height = 400), width = 12) ) ) ) server <- function(input, output) { # 生成第一个ggplot:累计输血患者趋势 output$plot1 <- renderPlot({ ggplot(data=o2outcomes, aes(x=transfusion_date, y=ID, group=1)) + geom_line(linewidth = 1.2) + ylim(0, 100) + labs(y = "Number of Patients Transfused", x = "Transfusion Date") + ggtitle("Number of Patients Transfused Over Time") + theme_minimal() }) # 生成第二个ggplot:患者呼吸支持及事件趋势 output$plot2 <- renderPlot({ Figure %>% drop_na(Requirement) %>% ggplot() + geom_line(aes(x=Day, y=Patient, group=Patient, col=Requirement), linewidth=2.5) + scale_color_manual(values=cols) + scale_y_continuous(trans="reverse", breaks=seq(1,50,1)) + scale_x_continuous(breaks=seq(-14,24,1)) + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), plot.title = element_text(hjust = 0.5)) + geom_vline(xintercept=0, linetype="dashed") + geom_point(data=Figure_Event, aes(x=Day, y=Patient, shape=Event), size=4) + scale_shape_manual(values=c(15,22)) + labs(y = "Patient ID", x = "Day Relative to Transfusion", title = "Respiratory Support & Patient Outcomes") + scale_color_discrete(breaks=c("AmbientAir","LowFlow","HighFlow", "NIPPV","MechanicalVentilation","ECMO")) }) } # 启动Shiny应用 shinyApp(ui, server)
代码说明:
- 我帮你禁用了侧边栏(
disable = TRUE),因为你不需要用户交互 - 两个图表分别放在独立的
fluidRow中,实现上下排列,每个占满整个页面宽度 - 数据处理部分已经整合到代码中,运行前请确保你的CSV文件路径正确
- 图表添加了
theme_minimal()和标题居中的设置,优化视觉效果
二、关于将ggplot保存为PDF后插入仪表盘的问题
当然可以实现,但直接在Shiny中生成ggplot并输出会更高效(无需额外的文件读写和格式转换)。如果确实需要用PDF文件插入,有两种方法:
方法1:先保存ggplot为PDF,再转换为图片插入
需要用到magick包将PDF转换为图片格式(如PNG),然后用imageOutput显示:
# 先保存ggplot为PDF(可以在数据处理部分执行) ggsave("transfusion_trend.pdf", plot = ggplot(data=o2outcomes, aes(x=transfusion_date, y=ID, group=1)) + geom_line(), width = 10, height = 6) # 在Shiny的server中转换PDF为图片并输出 library(magick) output$plot1_from_pdf <- renderImage({ # 将PDF转换为PNG img <- image_read_pdf("transfusion_trend.pdf") image_write(img, "transfusion_trend.png") list(src = "transfusion_trend.png", width = "100%") }, deleteFile = TRUE) # 在ui中添加对应的输出 box(imageOutput("plot1_from_pdf", height = 350), width = 12)
方法2:直接在Shiny中渲染PDF(不推荐,兼容性差)
部分浏览器支持直接嵌入PDF,但体验不好,需要用tags$iframe:
# 在ui中添加 box(tags$iframe(src = "transfusion_trend.pdf", width = "100%", height = 350), width = 12)
总结:
- 优先选择直接在Shiny中生成ggplot的方式,代码更简洁、运行更流畅
- 如果必须用PDF文件,推荐方法1(转成图片),兼容性更好
内容的提问来源于stack exchange,提问作者htxepidemiologist
相关产品推荐
相关产品推荐

