Variable number of plots - reactive

747 views
Skip to first unread message

Ben Ward

unread,
Jan 30, 2015, 1:31:49 PM1/30/15
to shiny-...@googlegroups.com
I've recently seen this example of generating multiple plot outputs programmatically:

Here is functional code to make a variable number of plots based on the number of columns.  I suggest using this as a starting point, and adding small amounts of code until you pinpoint what exactly is breaking it.

server.r:
max_plots <- 100
library(shinyIncubator)

shinyServer(function(input, output) {

sampletable=reactive({
if(input$go<1)
return()

x1=c(106:110, 21:25)
x2=c(101:105, 201:205)
x3=c(21:25, 31:35)
x4=c(51:60)
input$go
x=isolate(rbind(x1,x2,x3,x4))

x
})
  # Insert the right number of plot output objects into the web page
  output$plots <- renderUI({
    plot_output_list <- lapply(1:ncol(sampletable()), function(i) {

      plotname
<- paste("plot", i, sep="")
      plotOutput
(plotname, height = 280, width = 250)
   
})

    # Convert the list to a tagList - this is necessary for the list of items
    # to display properly.
    do.call(tagList, plot_output_list)
  })

  # Call renderPlot for each one. Plots are only actually generated when they
  # are visible on the web page.
  for (i in 1:max_plots) {
    # Need local so that each item gets its own number. Without it, the value
    # of i in the renderPlot() will be the same across all instances, because
    # of when the expression is evaluated.
    local({
      my_i <- i
      plotname <- paste("plot", my_i, sep="")

      output[[plotname]] <- renderPlot({
        plot(sampletable()[,my_i], sampletable()[,my_i],
             xlim = c(min(sampletable()[,my_i]), max(sampletable()[,my_i])),
             ylim = c(min(sampletable()[,my_i]), max(sampletable()[,my_i])),
             main = "look at all those things"        )
      })
    })
  }
})

ui.r

library(shinyIncubator)
shinyUI(pageWithSidebar(

  headerPanel("Dynamic number of plots"),

  sidebarPanel(
    sliderInput("n", "this isn't used, I used the ncol function instead, but feel free to move the slider for fun.", value=1, min=1, max=5),
  actionButton("go", "Update")
  ),

  mainPanel(
    # This is the dynamic UI for the plots
    uiOutput("plots")
  )
))

My question is, how easy is this to be made reactive? Say instead of max_plots, there is an input value that A). is evaluated to determine the number of plots, and prep the renderPlot elements, and then B). send them the appropriate plots generated? I wondered if this might be done with two reactive statements? One depends on the input variable and then makes the renderPlot elements for the UI, then the code to provide those with the plots is in a reactive element that depends on the previous?

Thanks,
Ben.

Joe Cheng

unread,
Jan 30, 2015, 1:42:30 PM1/30/15
to Ben Ward, shiny-...@googlegroups.com
Yes, it's quite straightforward. I believe this should work:

shinyServer(function(input, output, session) {
  output$plots <- renderUI({
    lapply(seq_len(input$plotCount), function(x) {
      output[[paste0("plot", x)]] <- renderPlot({
        ...
      })
      plotOutput(paste0("plot", x))
    })
  })
})

--
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/ff5553de-4a36-414e-a6b7-c77b489cd1f2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Noah Leidinger

unread,
Jun 20, 2020, 1:18:03 PM6/20/20
to Shiny - Web Framework for R
Thank you so much. I was struggling for 4 hours to get this to work and with this simple solution it worked instantly!
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages