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

Shiny应用单运行按钮生成多图表及一键清空功能实现咨询

实现方案

1. 核心逻辑说明

  • 单个运行按钮触发所有计算:通过eventReactive将所有图表对应的数据源计算逻辑绑定到运行按钮,所有输出自动响应按钮点击事件
  • 清空按钮功能:通过update*系列函数重置所有输入组件,同时清空所有输出内容
  • 下载功能:为每个图表配置独立的图片、数据下载按钮,通过downloadHandler实现导出

2. 完整修改代码

2.1 调整绘图函数

首先修改plotinput函数,使其同时返回绘图所用的数值矩阵,方便后续导出CSV:

plotinput <- function(P){
      PG <- as.matrix(P)
      A = PG[1,];  B = PG[2,]; C = PG[3,]
      Z = matrix(0,LDR,LRP)
      for (j in 1:LRP) {
        for (i in 1:LDR) {
          if (C[i] != 0) { 
            Z[i,j] = A[i] +((B[i]/C[i])*(((-log(1-(1/RP[j])))^-C[i])-1)) 
          } else { 
            Z[i,j] = A[i] +((B[i])*(-log(-log(1-(1/RP[j]))))) 
          }
        }
      }
  
  col_set <- rainbow(nrow(Z))
  matplot(Z,type = "o", lty = "solid", 
          lwd = 2, xlab = "Duration (hr)",ylab = "Intensity (mm/hr)", 
          col = col_set, cex.lab = 1.5, cex.axis=1.5, 
          cex.main=1.5, cex.sub=1.5, pch = 21, xaxt='n')
  # 返回数值矩阵用于导出
  return(invisible(Z))
}

2.2 修改UI部分

在数据导入页添加运行/清空按钮,每个图表页添加下载按钮:

library(shiny)
library(shinydashboard)

ui <- dashboardPage(dashboardHeader(title = "IDF"),
                dashboardSidebar(
                                 sidebarMenu(
                                   menuItem("Data", tabName = "dataimport"), 
                                   menuItem("Stationary IDF", tabName = "Stidf"),
                                   menuItem("Non-stationary IDF", tabName = "NStidf"),
                                   menuItem("IDF under climate change", tabName = "Gcmidf"))),
                dashboardBody(
                  tabItems(
                    tabItem(tabName = "dataimport",
                            fileInput("file","Hourly precipitation data(.csv format)",accept = ".csv"),
                            checkboxInput("header", "Header", TRUE),
                            radioButtons('UserCov',"Mention if there is a local covariate to be added, if Yes add the file", 
                                                                                      choices = list("No" = 1,"Yes" = 2), inline = T),
                            fileInput("cov","Local covariate data(.csv format)",accept = ".csv"),
                            checkboxInput("head", "Header", TRUE),
                            numericInput("lat","Latitude", value = c()),
                            numericInput("lon","Longitude", value = c()),
                            radioButtons('gcm', "Select the GCM", choices = list("MPI" = 1,"MRI" = 2,"CNRM"=3,"EC" =4,"MIR"=5), inline = T),
                            sliderInput("fut", label = h4("Select the starting point of time period"),min = 2015, max = 2100, value =  2020),
                            # 新增运行和清空按钮
                            br(),
                            actionButton("run_btn", "生成所有图表", icon = icon("play"), style = "background: #00a65a; color: white; margin-right: 10px;"),
                            actionButton("reset_btn", "重置所有内容", icon = icon("refresh"), style = "background: #dd4b39; color: white;")
                            ),
                    tabItem(tabName = "Stidf",
                            # 新增下载按钮
                            downloadButton("dl_SIDF_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                            downloadButton("dl_SIDF_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                            plotOutput('SIDF')), 
                    tabItem(tabName = "NStidf",
                            downloadButton("dl_NIDF_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                            downloadButton("dl_NIDF_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                            plotOutput('NIDF')),
                    tabItem(tabName = "Gcmidf", 
                            tabsetPanel(type = "tabs",
                                        tabPanel("s1",
                                                 downloadButton("dl_p1_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                                                 downloadButton("dl_p1_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                                                 plotOutput('plot1')),
                                        tabPanel("s2",
                                                 downloadButton("dl_p2_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                                                 downloadButton("dl_p2_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                                                 plotOutput('plot2')),
                                        tabPanel("s3",
                                                 downloadButton("dl_p3_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                                                 downloadButton("dl_p3_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                                                 plotOutput('plot3')),
                                        tabPanel("s5", 
                                                 downloadButton("dl_p4_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"),
                                                 downloadButton("dl_p4_data", "下载CSV数据", style = "margin-bottom: 10px;"),
                                                 plotOutput('plot4'))))
                            )))

2.3 修改Server部分

绑定按钮事件,添加下载逻辑:

server <- function(input, output,session) {
  # --------------- 运行按钮绑定所有数据源计算 ---------------
  # 你原有逻辑中的plotSt、plotNSt、PCC1-PCC4都改为eventReactive绑定运行按钮
  # 示例(替换为你原有计算逻辑即可):
  plotSt <- eventReactive(input$run_btn, {
    # 此处放你原本plotSt()的计算逻辑
    req(input$file)
    # 原有逻辑保留
  })
  plotNSt <- eventReactive(input$run_btn, {
    # 此处放你原本plotNSt()的计算逻辑
    req(input$file)
    # 原有逻辑保留
  })
  PCC1 <- eventReactive(input$run_btn, {
    # 此处放你原本PCC1()的计算逻辑
    req(input$file, input$gcm)
    # 原有逻辑保留
  })
  PCC2 <- eventReactive(input$run_btn, {
    # 此处放你原本PCC2()的计算逻辑
    req(input$file, input$gcm)
    # 原有逻辑保留
  })
  PCC3 <- eventReactive(input$run_btn, {
    # 此处放你原本PCC3()的计算逻辑
    req(input$file, input$gcm)
    # 原有逻辑保留
  })
  PCC4 <- eventReactive(input$run_btn, {
    # 此处放你原本PCC4()的计算逻辑
    req(input$file, input$gcm)
    # 原有逻辑保留
  })

  # --------------- 图表渲染逻辑保留,自动响应运行按钮 ---------------
  output$SIDF <- renderPlot({
    req(plotSt())
    # 保存绘图返回的数值矩阵用于导出
    sidf_data <<- plotinput(plotSt())
  })
  output$NIDF <- renderPlot({
    req(plotNSt())
    nidf_data <<- plotinput(plotNSt())
  })
  
  output$plot1 <- renderPlot({
    req(PCC1())
    p1_data <<- plotinput(PCC1())
  })
  output$plot2 <- renderPlot({
    req(PCC2())
    p2_data <<- plotinput(PCC2())
  })
  output$plot3 <- renderPlot({
    req(PCC3())
    p3_data <<- plotinput(PCC3())
  })
  output$plot4 <- renderPlot({
    req(PCC4())
    p4_data <<- plotinput(PCC4())
  })

  # --------------- 下载逻辑 ---------------
  # SIDF下载
  output$dl_SIDF_plot <- downloadHandler(
    filename = function() {paste0("固定IDF曲线_", Sys.Date(), ".png")},
    content = function(file) {
      png(file, width = 10, height = 8, res = 300, units = "in")
      plotinput(plotSt())
      dev.off()
    }
  )
  output$dl_SIDF_data <- downloadHandler(
    filename = function() {paste0("固定IDF数据_", Sys.Date(), ".csv")},
    content = function(file) {
      write.csv(sidf_data, file, row.names = FALSE, fileEncoding = "GBK")
    }
  )
  # 剩余5个图表的下载逻辑和上面完全一致,替换对应的变量名和文件名即可,示例省略

  # --------------- 清空按钮逻辑 ---------------
  observeEvent(input$reset_btn, {
    # 重置所有输入项
    updateFileInput(session, "file", value = NULL)
    updateCheckboxInput(session, "header", value = TRUE)
    updateRadioButtons(session, "UserCov", selected = 1)
    updateFileInput(session, "cov", value = NULL)
    updateCheckboxInput(session, "head", value = TRUE)
    updateNumericInput(session, "lat", value = NA)
    updateNumericInput(session, "lon", value = NA)
    updateRadioButtons(session, "gcm", selected = 1)
    updateSliderInput(session, "fut", value = 2020)
    # 清空所有输出
    output$SIDF <- renderPlot({NULL})
    output$NIDF <- renderPlot({NULL})
    output$plot1 <- renderPlot({NULL})
    output$plot2 <- renderPlot({NULL})
    output$plot3 <- renderPlot({NULL})
    output$plot4 <- renderPlot({NULL})
    # 清空缓存的数据
    rm(list = c("sidf_data", "nidf_data", "p1_data", "p2_data", "p3_data", "p4_data"), envir = .GlobalEnv)
  })
}
shinyApp(ui, server)

3. 注意事项

  • 原代码中使用的LRP、LDR、RP变量需要确保在应用运行环境中可访问,若为局部定义请调整作用域或作为参数传入plotinput函数
  • 剩余5个图表的下载逻辑参考已给出的SIDF下载代码替换对应变量即可,无需额外修改逻辑
  • 若需要导出PDF格式的图表,仅需将下载图片的png()函数替换为pdf(),同时修改文件名后缀即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:24:08