How to update plot in a while loop...some way to link renderPlot to newly changed data?

1,371 views
Skip to first unread message

rifkinlab

unread,
May 2, 2015, 2:43:12 AM5/2/15
to shiny-...@googlegroups.com
I have a question related to some others that have been asked, but it doesn't quite match and so I'm stuck and would appreciate some help.

A stripped down scenario is:

- Start with a square array of zeros.
- Have a sliderInput in the ui that gives the starting location.
- Have another sliderInput that gives the size of the array
- Starting from that location and going to the end, change the 0s to 1s one at a time and use image to display the result every iteration

In regular R code this would be:

theGrid <- array(0,dim=c(size,size))#size would be set from input$size
loc <- sample(1:(
size*size),1)  # in shiny this would be taken from input$startLoc...but I'm not sure where
theGrid[loc]<-1
image(theGrid)
while (loc<(size*size)) {
  loc<-loc+1
  theGrid[loc]=1
  image(theGrid)

}

I'm having problems in translating this to shiny.

Here is an attempt:

shinyServer(function(input,output,session){
 
  rv<-reactiveValues()

  getsize<-reactive({input$size})
  getloc<-reactive({input$startLoc})

  observe({
    theGrid<-array(0,dim=c(getsize(),getsize()))
    rv$grid<-theGrid
    loc<-getloc()
    rv$grid[loc]=1
    while (loc<(getsize()*getsize()){
      loc<-loc+1
      rv$grid[loc]=1
    }
  })
  output$gridPlot<-renderPlot({
    if (input$goButton == 0){
      return()
    }
    image(rv$grid)
  })
 
})

I feel like I have some of the pieces but perhaps in the wrong places.  Similar posts suggest invalidateLater or reactiveTimer, but I don't get how to use them here.
Thanks.
 

rifkinlab

unread,
May 2, 2015, 2:48:41 AM5/2/15
to shiny-...@googlegroups.com
Addendum:  I realize that the example above is rather banal  and that there are lots of ways to do this specific task more efficiently.  In my actual program, the stuff in the while loop that updates the grid is much more complicated.  The key, though, is that the grid is changing each iteration, and I'd like shiny to render the image of that grid each iteration.

Joe Cheng

unread,
May 2, 2015, 1:20:31 PM5/2/15
to rifkinlab, shiny-...@googlegroups.com
Do you want the user to have to intervene (push the button) between each iteration? Do you want the user to be able to jump to different points in the timeline, or is this always proceeding forward step-wise?

Sent from Outlook




On Fri, May 1, 2015 at 11:48 PM -0700, "rifkinlab" <sari...@ucsd.edu> wrote:

Addendum:  I realize that the example above is rather banal  and that there are lots of ways to do this specific task more efficiently.  In my actual program, the stuff in the while loop that updates the grid is much more complicated.  The key, though, is that the grid is changing each iteration, and I'd like shiny to render the image of that grid each iteration.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/05d863f6-4f71-46dd-9bfd-b25f337c2626%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

rifkinlab

unread,
May 2, 2015, 3:30:43 PM5/2/15
to shiny-...@googlegroups.com, sari...@ucsd.edu
The user just sets some initial values through sliders/radio buttons/editboxes  and then the iterations proceed without any user input until done. 

I guess it would be nice once it is done if the user could change the initial values once a simulation is done and then the new simulation would run.  I thought I'd use an actionButton so that the user could set the values and then it would start once the actionButton is pressed.

Making it slightly more complicated (perhaps) would be:  if the user changes the input values while the iterations (while loop) are going, then the it doesn't start over but just uses the new input values from then on. That would be a bonus.   I suppose these would just be reactive values, but I'm still learning how program flow works in shiny.

Thanks.


rifkinlab

unread,
May 2, 2015, 3:33:21 PM5/2/15
to shiny-...@googlegroups.com, sari...@ucsd.edu
Whether the user changes input values or not, though, the idea would be that the grid that is plotted is updated on the fly and not stored (it could take a while to run), so it wouldn't be possible to jump between different timepoints.

rifkinlab

unread,
May 2, 2015, 4:51:15 PM5/2/15
to shiny-...@googlegroups.com, sari...@ucsd.edu
An example:

https://ucsdbieb143.shinyapps.io/EpiWeek5/

Except here the plot  updates after the while loop is done running instead of during the while loop.  Then it appears to cycle back and restart the simulation and run over and over again.

Mark

unread,
May 9, 2015, 6:36:24 AM5/9/15
to shiny-...@googlegroups.com
I currently have a similar problem (trying to output text for each loop iteration) and I came across this code: http://stackoverflow.com/questions/27194893/reset-animation-in-shiny-r-studio

Personally I'm having trouble converting it to my needs - I think I'm misunderstanding something fundamental - but the code in the example does work.

rifkinlab

unread,
May 9, 2015, 4:34:23 PM5/9/15
to shiny-...@googlegroups.com
Thanks very much for those links, Mark.  Based on them I got it to work.  One key realization that my while loop was unnecessary since shiny is continually running and checking things.  So I changed it into an if statement.

In my renderPlot function I just had the code to do the plot.  No computations there.

Then all the computations and updating were in an observe({isolate({  block, and I updated the values of components of a reactiveValues data structure.

I'm not sure yet how to get it not to reset the plot when it is done.

shinyUI<-(
  fluidPage(
   
    # Application title
    titlePanel("Simulating Infection"),
   
    # Sidebar with a slider input for proportion vaccinated
    sidebarLayout(
      sidebarPanel(
        sliderInput("size",
                    "Grid size",
                    min = 4,
                    max = 151,
                    value = 4,
                    animate=F,
                    step=5),
        actionButton("goButton", "Go!"),
        actionButton("reset","Stop/Reset")
      ),
      # Show a plot of the grid
      mainPanel(
        plotOutput("gridPlot"))
    )
  )
)
########################################################
shserver<-(function(input,output,session){
 
  gr<-reactiveValues(ifield=array(0,dim=c(2,2)),counter=1,resetHelper=0)#just to initialize ifield to some array



output$gridPlot<-renderPlot({
  image(gr$ifield)
})

observe({
  if(gr$resetHelper==0){
    return(NULL)
  }
  isolate({
    if (gr$counter==1){ #initialization code
      gr$ifield=array(data=0,dim=c(input$size,input$size))
      gr$ifield[gr$counter]=1
    }
    if (gr$counter>1){
      gr$ifield[gr$counter]=1
    }
      gr$counter=gr$counter+1

    })
 
  if (((isolate(gr$resetHelper==1 & gr$counter<=input$size*input$size))))
    invalidateLater(200,session)
  })

observe({
  if(input$goButton>0){
    gr$resetHelper<<-1
  }
 
})

observe({
  if (input$reset>0){
    gr$counter <<- 1
    gr$resetHelper<<-0
  }
})
observe({
  if (input$size>0){
    gr$resetHelper<<-0
  }
 
})
})
##############
runApp(list(ui=shinyUI,server=shserver))

Mark

unread,
May 10, 2015, 12:41:45 PM5/10/15
to shiny-...@googlegroups.com
Your welcome, and thanks for sharing your code Scott. 

I'm still trying to get my head around the reactive / observe / isolate interactions, and seeing examples like yours is certainly helping. 

I'm still unclear as to whether I should be using an explicit loop or just free running as yours does. My issue is that my code needs to be able to stop part way through if it meets certain success criteria. If I'm interpreting correctly I think that's what you're using your gr$resetHelper variable for? Reset seems to be a common issue based on all the posts I've been reading.

I think Shiny is brilliant but I find I'm now spending more time on developing the GUI than I did on my underlying genetic algorithm code. But I should have one heck of a demonstration when it's finished :-)
Reply all
Reply to author
Forward
0 new messages