43234

Plotting the same output in two tabPanels in shiny

Question:

I'm trying to plot the same histogram in two separate tab panels within a tabBox in shiny. I can plot the data in one of the tabs, but then when I add the code for the other it seems to break the app. Below is an example of I'm trying to do:

library(shiny) library(dplyr) data(mtcars) body <- dashboardBody( fluidRow( tabBox( title = "miles per gallon", id = "tabset1", height = "250px", tabPanel("Tab1", plotOutput("plot1")), tabPanel("Tab2", plotOutput("plot1"), "test") # the app 'breaks' when I add in the **plotOutput("plot1")** here... however it works when I remove it ) ) ) shinyApp( ui = dashboardPage( dashboardHeader(title = "Test"), dashboardSidebar(), body ), server = function(input, output) { output$plot1 <- renderPlot({hist(mtcars$mpg)}) } )

In this particular example, I could just add another line in the server like this

output$plot2 <- renderPlot({hist(mtcars$mpg)})

and then call plot2, but my actual app is a bit more complex than the above example, so I'd like to plot plot1 in both tabs.

Answer1:

When you create a shiny app, you are creating a HTML site and the outputs are in div containers with ids. So what you are trying without knowing is to create two div container with the same id. This will not work. For a discussion, see here: <a href="https://stackoverflow.com/questions/5611963/can-multiple-different-html-elements-have-the-same-id-if-theyre-different-eleme" rel="nofollow">Can multiple different HTML elements have the same ID if they're different elements?</a>

What you can do is to wrap the server code in a lapply()function and generate two ids:

lapply(1:2, function(nr){ output[[paste0("plot", nr)]] <- renderPlot({hist(mtcars$mpg)}) })

and then call plotOutput("plot1") and plotOutput("plot2"). There are also other possibilities to use only one output in a combination with conditionalPanels(), but i think this way should work better for you.

Answer2:

BigDataScientist's answer is great and very scalable.

But for situations where you only have one or two outputs that you want to repeat, I think the easiest and most readable solution is to assign them all to the same render function. For example, this would be:

output$plot1 <- output$plot2 <- renderPlot({ hist(mtcars$mpg) })

Here's the full working app using this solution:

<pre class="lang-r prettyprint-override">library(shiny) body <- dashboardBody( fluidRow( tabBox(title = "miles per gallon", id = "tabset1", height = "250px", tabPanel("Tab1", plotOutput("plot1")), tabPanel("Tab2", plotOutput("plot2"), "test") ) ) ) shinyApp( ui = dashboardPage( dashboardHeader(title = "Test"), dashboardSidebar(), body ), server = function(input, output) { output$plot1 <- output$plot2 <- renderPlot({ hist(mtcars$mpg) }) } )

Recommend

  • shiny unable to see dataframe from reactive data object
  • Shiny + GGplot - mouse click coordinates
  • Reactive DateRangeInput for Shiny
  • How keep tabs in one line
  • Update data frame of click data with user input
  • Using Shiny to dispay conditional ggvis OR ggplot
  • nopCommerce 2.40 Admin Product Edit Addition
  • Place tab in Shiny tabsetPanel on the right
  • Creating if statements to filter posts by category from cpt in wordpress
  • Data object not found when deploying shiny app
  • angular-chart zero dimensions inside angular-strap panel
  • grid.arrange with John Fox's effects plots
  • Inconsistency when setting figure size using pandas plot method
  • dynamically deleting tab panel in tab container in asp.net using vb.net
  • Titanium - Passing Variable to new window
  • Add link panel tabs in Shiny with various top level navigation bars
  • Shiny: Independently navigate two tabsetPanels
  • Write Text In A Already Existing Text File VB.NET
  • How to change bootstrap responsive style?
  • VBA: Selecting from dropdown menu to reload page and scraping data
  • Can I set html class dynamically? Or how does Shiny set 'html'.hasClass('Shiny-busy&#
  • GWT:how to make tabPanel to 100% height
  • How to display, fetched data from API, in the html page?
  • Update multiple tables in a single query in mysql
  • GWT - Implement programmatic tab selection of a TabLayoutPanel and then scroll to a particular eleme
  • how to dynamically enable a disabled ion-tab?
  • Cannot end a section without first starting one in Laravel
  • respondsToSelector - not working
  • Can I disable IE compatibility mode only for content within a ?
  • Gforce min not supported for character in data.table
  • Change URL of the windows for every different Tab
  • force json_encode to create strings
  • Display issues when we change from one jquery mobile page to another in firefox
  • Deselecting radio buttons while keeping the View Model in synch
  • How to set/get protobuf's extension field in Go?
  • JSON with duplicate key names losing information when parsed
  • How to show dropdown in excel using jrxml (jasper api)?
  • Jquery - Jquery Wysiwyg return html as a string
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • How to stop GridView from loading again when I press back button?