You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用多页PDF导出问题:图表未分页及尺寸调整需求

问题解决方案

1. 每页一张图表的设置问题

你当前代码里marrangeGrob的nrow = length(plot.list)会把所有图表挤在同一页的多行中,要实现每页一张图,只需将nrow和ncol都设为1即可,marrangeGrob会自动根据图表数量分页,每张图单独占一页。

2. 调整图表尺寸的方法

有两种常用的尺寸控制方式:

  • 直接在marrangeGrob中设置width和height参数,统一控制所有图表的尺寸
  • 在ggsave中设置width、height和units(如"in"、"cm"),优先级高于前者

修改后的完整代码

library(shiny)
library(data.table)
library(tidyverse)
library(shinydashboard)
library(gridExtra) # 显式加载marrangeGrob所属的包

### UI & Module -------------------
plotUI <- function(id) {
  ns <- NS(id)
  plotOutput(ns("myplot"))
}

plotServer <- function(id,groups) {
  moduleServer(
    id,
    function(input, output, session) {
      filtered.data <- reactive(iris %>% filter(Species == groups))

      create_graph <- reactive(filtered.data() %>% ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
                                 geom_col())
  
      output$myplot <- renderPlot(create_graph())  
      
      return(list(graph = create_graph))
    }  
  )    
}


### UI part -----------------------
ui <- dashboardPage(
  title="test",
  dashboardHeader(),
  dashboardSidebar(downloadButton('download')),
  dashboardBody(uiOutput('tablist'))
)

### Server part ----------------------------
server = function(input, output) { 
  groups <- reactive(unique(iris$Species))
  ntabs <- reactive(length(groups()))

  allplots <- reactiveVal()
  
  observeEvent(ntabs(),{
    plot <- lapply(1:ntabs(), function (i) {
      plotServer(paste0("plot",i),groups()[i])
    })
    allplots(plot)
  })  
  
  output$tablist = renderUI({
    addtabs <- lapply(1:ntabs(),function (i) {
      tabPanel(
        groups()[i],
        plotUI(paste0("plot",i)),
      )
    })
    do.call(tabsetPanel, addtabs)
  })
  
  output$download <- downloadHandler(
    filename = function() {
      paste0("plots-", Sys.Date(), ".pdf")
    }, content = function(file) {
      plot.list <- allplots()
      # 核心修改:设置每页1张图,并定义尺寸
      grob_list <- marrangeGrob(
        lapply(plot.list, function(x) x$graph()),
        ncol = 1, nrow = 1,  # 每页1行1列
        width = 6, height = 8 # 图表宽6英寸、高8英寸,可按需调整
      )
      ggsave(file, grob_list, units = "in")
    }
  )
}

### Running part ----------------------------
shinyApp(ui, server,enableBookmarking = "server")

关键修改点说明

  • 补充加载gridExtra包:marrangeGrob属于该包,显式加载避免潜在依赖问题
  • 调整marrangeGrob布局参数:nrow=1, ncol=1确保每页只显示一张图表
  • 尺寸配置:通过marrangeGrob的width和height参数统一设置图表尺寸,也可在ggsave中单独调整

内容的提问来源于stack exchange,提问作者southwind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:40:21