【问题标题】:Rendering Inside ObserveEvent (Dynamic Plot Generation)在 ObserveEvent 内部渲染(动态绘图生成)
【发布时间】:2015-08-01 10:14:51
【问题描述】:

我正在尝试重新创建 https://gist.github.com/wch/5436415/,但通过按钮添加图。我认为这需要我沿着这些线修改链接上的server.r 代码(图表名称相关变量是通过reactiveValues 创建的) -

observeEvent(
      input$buttonAddData, 
      {
         ...
         newchartname = c(newchartname,newchartname)
         output[[newchartname]] = renderPlot({
            ...
         })
      }
)

output$plots = renderUI(
      {

         plot_output_list <- lapply(
            seq(length(allthechartnames)), 
            function(i) {
               plotname <- paste(
                  isolate(allthechartnames)[i]
               )
               plotOutput(plotname, height = 280, width = 250)
               cat(plotname,'\n')
            }
         )

         # Convert the list to a tagList - this is necessary for the list of items
         # to display properly.
         do.call(tagList, plot_output_list)

      }
   )

但这似乎没有进入在 observeEvent 中创建图表本身的原始循环,这导致 renderUI 块内没有图表。

有什么建议吗?

【问题讨论】:

  • 你不应该在观察者内部调用渲染函数。相反,使用reactiveValues 并更改观察者中反应值的值,并将该值用作渲染函数中的依赖项
  • @daattali - 在上面的代码中,我尝试将一个元素添加到reactivevalues(称为)的列表中,并将在observe 中创建的图表分配给它。我不确定如何在渲染位中替换它。我做不到plotname = &lt;listofreactivevalues&gt;$&lt;chartname&gt;
  • 如果您可以提供工作代码而不是 sn-ps,可能更容易帮助理解问题/解决方案
  • 我正在尝试按照这些思路做一些事情 = gist.github.com/wch/5436415 但不是定义的滑块,我想要一个生成随机数据并为每个随机数据生成添加图的按钮。这有帮助吗?如果没有,请告诉我,我将编写我的代码版本并将其发布在问题上。

标签: r ggplot2 shiny


【解决方案1】:

我不太了解您问题中的代码,所以我有点忽略了它,只是从要点中获取了 Winston 的代码,并使其与按钮而不是滑块一起工作。我希望这就是你的意思?另外,我确实必须在观察者内部使用渲染,这让我不满意:/

runApp(shinyApp(
  ui = fluidPage(
    headerPanel("Dynamic number of plots"),

    mainPanel(
      actionButton("addplot", "Add plot"),
      uiOutput("plots")
    )
  ),
  server = function(input, output, session) {

    # A variable that keeps track of the number of plots we have
    values <- reactiveValues(
      numPlots = 1
    )

    # Whenever the "add plot" button is pressed, increment num plots by 1
    observeEvent(input$addplot, {
      values$numPlots <- values$numPlots + 1
    })

    # Dynamically generate the UI that creates all the plots
    output$plots <- renderUI({
      # Create a list of `plotOutput` objects (for each plot, use a unique ID)
      plot_output_list <- lapply(1:values$numPlots, function(i) {
        plotname <- paste("plot", i, sep="")
        plotOutput(plotname, height = 280, width = 250)
      })

      # Place all the plot outputs inside a shiny `tagList()`
      do.call(tagList, plot_output_list)
    })

    # Every time the number of plots changes (button is clicked),
    # re-generate the render functions for all the plots
    observeEvent(values$numPlots, {
      for (i in 1:values$numPlots) {
        local({
          my_i <- i
          plotname <- paste("plot", my_i, sep="")

          output[[plotname]] <- renderPlot({
            plot(1:my_i, 1:my_i,
                 xlim = c(1, values$numPlots),
                 ylim = c(1, values$numPlots),
                 main = paste("1:", my_i, ".  n is ", values$numPlots, sep = "")
            )
          })
        })
      }
    })
  }
))

希望有帮助

【讨论】:

  • 我尝试运行它,但它说找不到 max_plots。我对按钮的需求正是为了完全克服对 max_plots 的需求。我可能有 10 个地块,我可能有 100 个,我不知道。
  • 哎呀,我的错,忘了在干净的会话上运行它。现在应该可以工作了。
  • 我是否认为由于 max_plots 被放置在观察内,我也可以调用它的反应值?
  • 太棒了!谢谢,这行得通!就我所知,为什么使用本地是一种不好的做法?
  • 我的代码没有max_plots,而是使用了一个反应值。我不太确定我是否理解这个问题
猜你喜欢
  • 2016-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 2018-04-17
  • 1970-01-01
相关资源
最近更新 更多