简体   繁体   English

强制闪亮以循环渲染图

[英]Force shiny to render plot in loop

I have a shiny app that runs a simulation. 我有一个运行模拟的闪亮应用程序。 The goal is to show the user the calculation steps in between as a plot. 目的是向用户显示绘图之间的计算步骤。

How do I force shiny to update the plot? 如何强迫闪亮来更新情节?

An MWE would look like this 一个MWE看起来像这样

library(shiny)

server <- function(input, output, session) {
  # base plot as a placeholder
  output$myplot <- renderPlot(plot(1:1, main = "Placeholder"))

  # wait until the button is triggered
  observeEvent(input$run, {
    print("Do some calculations in 3 steps")
    for (i in seq_len(3)) {
      print("Do some calculations")
      # ...
      x <- seq_len(i * 100)
      y <- (x + 1)^2 - 1 # this will do for now

      print("Plot the data ")

      # ISSUE HERE!
      # this should render the current step of the simulation, instead it 
      # renders only after the whole code is run (i.e., after step 3)
      output$myplot <- renderPlot(plot(x, y, main = sprintf("Round %i", i), type = "l"))

      print("Wait for 1 second for the user to appreciate the plot...")
      Sys.sleep(1)
    }
  })
}

ui <- fluidPage(
  actionButton("run", "START"),
  plotOutput("myplot")
)

shinyApp(ui = ui, server = server)

The issue is, that shiny runs the code and produces one plot at the end of the simulation, however, I want to get a plot at each simulation step (displayed for at least one second). 问题是,shiny运行代码并在模拟结束时生成一个图,但是,我想在每个模拟步骤中获得一个图(显示至少一秒钟)。

Any help/hint is greatly appreciated. 任何帮助/提示,​​我们将不胜感激。

Appendix 附录

I have looked at this post , but replacing the text with a plot/ renderPlot doesn't yield the correct results. 我看了这篇文章 ,但是用plot / renderPlot替换文本不会产生正确的结果。

You could nest an observer into an observeEvent to make it work. 您可以将observer嵌套到observeEvent以使其工作。 Based on Jeff Allen's code from the SO topic you linked. 基于您链接的SO主题中Jeff Allen的代码。

Crucial part: 关键部分:

observeEvent(input$run, {
    rv$i <- 0
    observe({
      isolate({
        rv$i <- rv$i + 1
      })

      if (isolate(rv$i) < maxIter){
        invalidateLater(2000, session)
      }
    })
  })

Full code: 完整代码:

library(shiny)

server <- function(input, output, session) {
  rv <- reactiveValues(i = 0)
  maxIter <- 3

  output$myplot <- renderPlot( {
    if(rv$i > 0) {
      x <- seq_len(rv$i * 100)
      y <- (x + 1)^2 - 1 # this will do for now
      plot(x, y, main = sprintf("Round %i", rv$i), type = "l") 
    } else {
      plot(1:1, main = "Placeholder")
    }
  })

  observeEvent(input$run, {
    rv$i <- 0
    observe({
      isolate({
        rv$i <- rv$i + 1
      })

      if (isolate(rv$i) < maxIter){
        invalidateLater(2000, session)
      }
    })
  })

}

ui <- fluidPage(
  actionButton("run", "START"),
  plotOutput("myplot")
)

shinyApp(ui = ui, server = server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM