Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update graph/plot with fixed interval of time

Tags:

I have a plot in Shiny UI. If I change any input parameter and through reactivity plot will change. But let's consider following situation:- The plot in Shiny UI plotting let say intra-day price move of a stock. And for that you query some live data source. Now If I create a refresh button and then if time passes by I keep on clicking on refresh button. The plot will be updated as new data arrives as time goes into that live data source. Now my question is I don't want to keep clicking on refresh button. But I want to run a loop with timer so that it will check over a fixed interval of time and as soon as new data comes the plot will auto update. Something sort of Google Finance Graphs which keeps updating over time.

So the problem can be simplified as follows :- Let's consider this example from Shiny itself :- ui.R

library(shiny)    

shinyUI(pageWithSidebar(    

  headerPanel("Hello Shiny!"),

  sidebarPanel(
    sliderInput("obs", 
                "Number of observations:", 
                min = 1,
                max = 1000, 
                value = 500)
  ),

  mainPanel(
    plotOutput("distPlot")
  )
))

and server.R

library(shiny)

shinyServer(function(input, output) {

  output$distPlot <- renderPlot({

    # generate an rnorm distribution and plot it
    dist <- rnorm(input$obs)
    hist(dist)
  })

})

Now I want to generate a different random sample from normal distribution without any input activity. So basically I want to call

dist <- rnorm(input$obs)
hist(dist)

again without changing sliderInput. Please help me find out how to do that.

like image 950
Indranil Gayen Avatar asked Aug 18 '13 18:08

Indranil Gayen


2 Answers

As an example you can run the following locally:

library(shiny)

runApp(list(
  ui = pageWithSidebar(    

  headerPanel("Hello Shiny!"),

  sidebarPanel(
    sliderInput("obs", 
                "Number of observations:", 
                min = 1,
                max = 1000, 
                value = 500)
  ),

  mainPanel(
    plotOutput("distPlot")
  )
),
  server =function(input, output, session) {
    autoInvalidate <- reactiveTimer(5000, session)
    output$distPlot <- renderPlot({
      autoInvalidate()
      # generate an rnorm distribution and plot it
      dist <- rnorm(input$obs)
      hist(dist)
    })

  }
))

A different normal sample will be generated every 5 seconds

like image 79
jdharrison Avatar answered Sep 22 '22 01:09

jdharrison


This can also be solved using reactivePoll. The code is a lot simpler. it has also the advantage that you can use a check-function that does not necessarily invalidate the reactive expression because time has passed. You are able to write less resource-demanding code that way.

The sample, however, uses only Sys.tim() as check function. Since Sys.time() will be different every time it is called, the check function ALWAYS indicates that an update is necessary.

library(shiny)

runApp(list(
  ui = pageWithSidebar(

    headerPanel("Hello Shiny!"),

    sidebarPanel(
      sliderInput("obs",
                  "Number of observations:",
                  min = 1,
                  max = 1000,
                  value = 500)
    ),

    mainPanel(
      plotOutput("distPlot")
    )
  ),
  server = function(input, output, session) {
    dist <- reactivePoll(5000, session, function () Sys.time(), function () {
      rnorm(input$obs)
    })

    output$distPlot <- renderPlot({
      hist( req(dist()) )
    })
  }
))
like image 1
Jan Avatar answered Sep 21 '22 01:09

Jan