【问题标题】:Wanna show the all changes(overlap) of for loop plot in r shiny想在 r shiny 中显示 for 循环图的所有变化(重叠)
【发布时间】:2018-03-07 08:42:35
【问题描述】:

这是关于Rshiny的询问。 我创建了一个名为 foo 的函数,如下所示。 在函数中,for 循环中有 5 个绘图。在 Shiny 中绘制绘图时,只有最后一个绘图可见,其余绘图不可见。你没看到正在创建(更新)五个地块吗?

foo <- function(iter = 5){
  for(j in 1:iter){
    plot(iris$Sepal.Length, iris$Sepal.Width, col = j)
    Sys.sleep(0.5)
  }
}

ui<-shinyUI(fluidPage(
sth 

 plotOutput('myplot')

))

server <- shinyServer(function(input, output, session){
sth ...

 output$myplot <- renderPlot({
     f <- foo(iter = 3)
    })  
 })

})

【问题讨论】:

  • 绘图已创建不用担心,它们只是不会呈现给客户端(因为您一直在覆盖它们),如果您想同时显示多个绘图,所有绘图都必须具有唯一的 ID然后为它们分配 ID(例如 plot1、plot2、plot3...)。这里有gist.github.com/wch/5436415 的例子,还有更多的例子
  • @PorkChop Thx,但我想做的是每个情节似乎都被覆盖和更新在一个地方......你能再帮我一次吗?

标签: r shiny interactive


【解决方案1】:

您不能在此处使用循环,因为服务器会在 UI 中呈现新输出之前执行所有代码,而Sys.sleep() 只会导致整个 R 进程停止指定的时间量。相反,您可以使用invalidateLater() 使您的绘图功能在设定的时间间隔内触发,同时仍然允许程序的其余部分正常运行。

library(shiny)

ui <- shinyUI(fluidPage(

  sliderInput("iterations", "Iterations", 1, 10, 3),
  sliderInput("interval", "Interval (ms)", 100, 1000, 500, step = 100),
  actionButton("draw", "Draw"),

  plotOutput('myplot')

))

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

  foo <- function(iterations = 5, interval = 500) {
    i <- 0
    output$myplot <- renderPlot({
      i <<- i + 1
      if (i < iterations)
        invalidateLater(interval)

      plot(iris$Sepal.Length, iris$Sepal.Width, col = i)
    })
  }

  observeEvent(input$draw, foo(input$iterations, input$interval))

})

shiny::shinyApp(ui, server)

现在,您还可以将每个间隔做某事的想法包装成一种延迟的map 函数,看起来像这样:

map_later <- function(.x, .f, ..., .interval = 500) {
    i <- 0
    observe({
      i <<- i + 1
      if (i < length(.x))
        invalidateLater(.interval)
      .f(.x[i], ...)
    })
}

这将产生一个更整洁、更易于管理的服务器:

ui <- shinyUI(fluidPage(

  plotOutput('myplot')

))

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

  map_later(1:5, function(i) {

    output$myplot <- renderPlot({
      plot(iris$Sepal.Length, iris$Sepal.Width, col = i)
    })

  }, .interval = 500)

})

shiny::shinyApp(ui, server)

在这里命名可能不是很好,但是嘿,它做了它应该做的。

【讨论】:

  • 感谢您的热心帮助!我的意图是创建一个函数,该函数创建一个函数,该函数在某个操作完成时绘制一个绘图,然后对其进行闪亮,以便用户可以看到更新视图的效果。所以我在for循环中创建了一个带有plot()的函数并尝试使用它,但是我不知道该怎么做...
  • 我再次编辑了答案,也许可以更好地展示这个想法。关键是,您不能在此处使用常规循环,因为这会阻止服务器呈现输出。相反,您可以使用这样的功能:“嘿,继续做你正在做的事情,但要在 500 毫秒内回来”
猜你喜欢
  • 2019-12-21
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
相关资源
最近更新 更多