0

I know renderPlot produces plot that can be shown on Shiny plotOutput function. I also know autoinvalidate() helps to calculate data reactively.

I am displaying a radar chart (in fact can be any chart) using the below codes:

output$plot2 <- renderPlot({
      autoInvalidate()
        p2<<-ggradar(mtcars_radar[i,])
    })

What I dont know is how to change the value of i from 1 to 300 during every event of autoinvalidate(). Or is there anyway I can change the row of data in plot so that the plot is dynamically animating every sec with a new row of data. Can anyone help me plz?

The full code is here:

library(shiny)
library(ggplot2)
 mtcars %>%
 rownames_to_column( var = "group" ) %>%
 mutate_at(vars(-group),funs(rescale)) %>%
 tail(4) %>% select(1:10) -> mtcars_radar

ui <- fluidPage(
  sidebarPanel(

    actionButton("button", "Go!")
  ),
  # Show the plot
  mainPanel(
    plotOutput("plot2")
  )
)

server <- function(input, output) {
  library(ggplot2)
  library(ggradar)
  suppressPackageStartupMessages(library(dplyr))
  library(scales)

  autoInvalidate <- reactiveTimer(2000)
  plot2 <- NULL


  output$plot2 <- renderPlot({
    ggradar(mtcars_radar[1,])
  })
  observeEvent(input$button,{

     output$plot2 <- renderPlot({
      autoInvalidate()
        p2<<-ggradar(mtcars_radar[i,])
        p2
    })
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

Any help please?

1 Answer 1

1

This is where you need a reactive value that stores the row index and changes every second. I do not have the library ggradar, so I will just print out the current row index value instead. I also used invalidateLater instead of reactiveTimer as suggested by Shiny documentation.

library(shiny)

ui <- fluidPage(
  verbatimTextOutput("debug")
)

server <- function(input, output) {

  row_idx_max <- 15
  row_idx <- reactiveVal(0)

  observe({
    isolate(row_idx(row_idx() + 1))
    cur_row_idx <- isolate(row_idx())
    if (cur_row_idx < row_idx_max) {
      invalidateLater(1000)
    }
  })

  output$debug <- renderPrint({
    row_idx()
  })
}

shinyApp(ui, server)
Sign up to request clarification or add additional context in comments.

4 Comments

There were some suggestions elsewhere telling using animating slider input. But that method was slow. Your suggestion is just fabulous. Thanks for saving me.
Just a bonus question please, how to stop invalidating after a certain number of iteration?
@doctshinds I updated the code to add a conditional test. invalidateLater does nothing but makes a schedule 'run this reactive block this time later', knowing what it does would help you better understand why this works. One thing you need to be cautious is that if you use row_idx() to subset the data, check if it's larger than 0 because I believe there is a tiny amount of time it was 0 before it was incremented to 1 immediately.
Thank you very much. Nice approach and thanks a lot for sharing your knowledge

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.