首页 > 解决方案 > 在闪亮的应用程序中绘制任意数量的垂直线

问题描述

我有一个很好的绘图功能,用 ggplot 完成,它还内置了绘制垂直线的功能,这些是我更大的 Shiny 应用程序的一部分。我试图为我的问题制作一个最小的可重现示例。这里是:

library(shiny)
library(ggplot2)

ui <- fluidPage(
  fluidRow(
    column(6, offset=1,
           plotOutput("plot", width="100%", height="500px")
    )
  ),
  fluidRow(
    column(2, offset=1,
           actionButton(inputId="go", label="Plot")
    ),
    column(2, offset=1,
           selectInput(inputId="number", label="Number of lines:",
                       choices=list("No lines"="0",
                                    "One line"="1",
                                    "Two lines"="2",
                                    "Three lines"="3"))
    )
  ),
  fluidRow(
    uiOutput("dynamic")
  )
)

server <- function(input, output, session) {

  # Function for n number of input boxes for
  # vertical line interception points in UI
  vertical_line_UI <- function(n) {
    fluidRow(
      column(4, offset=1,
             numericInput(inputId=sprintf("line%s", n),
                          label=sprintf("Line%s:", n),
                          value=5))
    )
  }

  # Rendering above in UI
  output$dynamic = renderUI({
    if (as.integer(input$number) > 0) {
      lapply(1:as.integer(input$number), vertical_line_UI)
    }
  })

  # Vertical line interception points
  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

  # Plot function
  plot_function <- function(data, lines=NULL) {
    p <- ggplot(data=data.frame(x=1:10, y=1:10),
                aes(x=x, y=y)) + geom_line() + theme_bw()
    if (!is.null(lines)) {
      for (n in 1:length(lines)) {
        p <- p + geom_vline(xintercept=lines[n])
      }
    }
    return(p)
  }

  # Rendering plot
  plot <- eventReactive(input$go, {
    plot_function(lines=lines())
  })

  output$plot <- renderPlot({
    plot()
  })

}

shinyApp(ui = ui, server = server)

我想做的是有一种比手动书写c(input$line1, input$line2, input$line3, ..., input$lineN)N 条垂直线更好的方法。无论如何,我可能会将其限制在 10-15 之间。

所以我想我的问题可以缩小如何表达

  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

以更流畅的方式输入 N 个输入,而不是手动写下每个输入。如果我有五条垂直线,我将只有 5 个输入变量等。

标签: rggplot2shiny

解决方案


推荐阅读