如何在R-Shiny输出中生成部分图形?

时间:2015-08-26 21:49:40

标签: r shiny

我希望我能简洁地解释一下。我有一个运行生态模拟的R函数,并返回一个输出列表(时间步长,种群大小,死亡历史,后代数量,类似的东西)。我希望在某些情况下减慢图形输出,以便学生可以在发生时看到人口动态。应显示绘图轴和标题,然后在0.5秒内出现代表累积后代的第一行,然后0.5秒后出现第二行累积后代,然后是第三行0.5秒后,直到新后代的整个队列出现绘制在“模拟”的末尾。

问题是应用程序在显示之前一直等到整个图像被渲染,因此我无法向学生展示“减慢”人口动态。输出图是空白的,直到所有这些0.5秒延迟完成,然后它立即渲染所有。甚至在for()循环之前的图形调用也会被抑制,直到循环结束。下面的代码示例不完整,正在进行中。

这是我的服务器代码 - 如果您在renderPlot命令中取消注释dev.new()调用,则应用程序完全按照需要工作,除了输出是在新的图形设备中,而不是在Shiny应用程序图窗口中:

shinyServer(function(input, output) {

observe({
    if(input$runSim == 0) return()
    isolate({
        sim <- reactive({
            switch(input$sim,
                   dorriefish = {
                        df.sim(input$S.df, input$p.df, show=FALSE)
                   }    # end case dorriefish
            )   # end switch(input$sim)
        })  # end reactive()

        output$modl.plot <- renderPlot({
            switch(input$sim,
                dorriefish = {
                    if (input$reps.df == 1)
                    {
                        # dev.new()
                          opar <- par(no.readonly=TRUE)                             
                        len <- length(sim()$offspring.t)
                        par(fig=c(0,1,0.1,0.9), xpd=NA)
                        plot(sim()$offspring.t, type="n", xlab="Time steps", ylab="Cumulative Doriefish offspring",
                            xlim=c(1, max(len, length(sim()$mass))))
                        mtext("Dorriefish living per time step (green = alive, red = dead):", side=3, at=(max(len)/2)+0.5,
                            line=4.2)
                         for(i in 1:nrow(sim()$mhistory))
                        {
                            z <- rep("green", length(sim()$mass))
                            z[sim()$mhistory[i,]] <- "red"
                            points(seq(1,len, length=length(sim()$mass)), rep(max(1.18*sim()$offspring.t), length(sim()$mass)),
                                pch=21, col="black", bg=z, cex=2.5)
                            lines(sim()$offspring.t[1:i], type="h")
                            Sys.sleep(0.5)
                        }
                        txt <- paste("Total offspring:", sim()$offspring,
                          "     Time to cohort extinction:", length(sim()$offspring.t), "time steps.")
                        mtext(txt, side=1, at=0, line=5, adj=0)
                        par(opar)

                    } # end if(input$reps.df == 1)
                }  # end case dorriefish
            )   # end switch(input$sim)
        })  # end renderPlot()

    })  # end isolate()
})  # end observe()

})  # end shinyServer()

这是UI代码:

library(shiny)

shinyUI(
fluidPage(
    titlePanel("BIOL 330 ecological simulations"),
    sidebarLayout(
        sidebarPanel("",
            helpText(HTML("<h3 style='text-align:center;'>Control Panel</h3>"), align='center'),
            tags$hr(style='height:2px; border-width:0; color:gray; background-color:gray'),

            # choose a simulation from a drop down menu
            selectInput("sim", HTML("<b>Select a simulation to explore:</b>"),
                # list the simulations available
                c("No simulation selected (Introduction)" = "none",
                "Dorriefish growth/reproduction trade-offs" = "dorriefish",
                "Optimal foraging" = "optfor")
            ),
            tags$hr(style='height:2px; border-width:0; color:gray; background-color:gray'),

            conditionalPanel(condition="input.sim=='dorriefish'",
                helpText(HTML("<b>Simulation model parameters:</b>")),
                sliderInput("S.df", label=div(HTML("Specify <em>S</em>, the switch point mass (g) for
                    transition from somatic growth to reproduction:")),
                    min = 1, max = 50, value = 10, step=5),
                sliderInput("p.df", label=div(HTML("Specify <em>p</em>, the probability of mortality
                by predation in any given time step:")),
                    min = 0, max = 1, value = 0.12, step=0.01),
                sliderInput("reps.df", label=div(HTML("Specify the number of full simulations to
                    run:")), min = 1, max = 100, value = 1, step=1)
            ),

            # bottom controls common to all panels
            conditionalPanel(condition="input.sim!='none'",
                tags$hr(style='height:2px; border-width:0; color:gray; background-color:gray'),
                fluidRow(column(4, actionButton("runSim", "Run simulation")),
                    column(4, actionButton("saveSim", "Save output file")),
                    column(4, actionButton("printSim", "Save/print plot"))),
                tags$hr(style='height:2px; border-width:0; color:gray; background-color:gray')
            )
        ),

        mainPanel("",

            # no model selected-- show information page
            conditionalPanel(condition="input.sim=='none'",
                includeHTML("www/simNoneText.html")
            ),

            tabsetPanel(id="outTabs", type="tabs",
                tabPanel("Plot", plotOutput("modl.plot")
                ),
                tabPanel("Summary"
                ),
                tabPanel("R Code"

                )
            )
        )
    )
)
)

所以要重复我的问题,如何让服务器显示每个时间步的累计子孙数,暂停0.5秒,然后显示下一个,直到显示所有模拟时间步骤?

谢谢,最诚挚的问候, --Mike C。

1 个答案:

答案 0 :(得分:1)

我试图阅读您的代码,这就是我所看到的:

我建议您使用uiOutput()函数来显示输出,以便ui.R变得更清晰,同时将计算放入server.R

要在人口增长(或其他任何事情)时模拟步骤,你可以在server.R中一次计算所有步骤,然后在for()循环内只显示一些数据,如{{1 }}

server.R