Thomas Rosa
Thomas Rosa

Reputation: 742

ggvis plot interferes with initial rendering of an R shiny app

I have an app like the one below, where I'm trying to render some html based on inputs and also display a ggvis plot. The plot seems to interfere with the htmlOutput() because it does not appear when the app is first loaded. When the input changes, it finally renders as expected.

Also, if we start the app on a tab without a ggvis plot, the html renders as expected from the start.

library(shiny)
library(ggvis)

ui <- fluidPage(
  sliderInput("slider", label = "slider", min = 1, max = 5, value = 3),
  htmlOutput("text"),
  tabsetPanel(
    # selected = "tab b", # if I uncomment this line, the htmlOutput works as expected
    tabPanel(title = "tab a", ggvisOutput("plot")),
    tabPanel(title = "tab b", "Static text")
  )
)

server <- function(input, output, session) {
  output$plot <- reactive({
    mtcars %>% ggvis(~mpg, ~hp) %>% layer_points() %>% bind_shiny("plot")
  })
  output$text = renderUI({
    paste0("The slider value is ", input$slider)
  })
}

shinyApp(ui = ui, server = server)

So, in this app, why doesn't the htmlOutput() appear when the app is loaded? How can I get it to appear when the app starts? Also, is this a bug of some sort?

Upvotes: 1

Views: 63

Answers (1)

ismirsehregal
ismirsehregal

Reputation: 33580

The issue here is, that you are assigning the plot as a reactive to the output via output$plot <- reactive(...).

Only bind_shiny should be used to connect a ggvis graphic to a shiny app:

library(shiny)
library(ggvis)
library(datasets)

ui <- fluidPage(
  sliderInput("slider", label = "slider", min = 1L, max = nrow(mtcars), value = nrow(mtcars), step = 1L),
  htmlOutput("text"),
  tabsetPanel(
    # selected = "tab b", # if I uncomment this line, the htmlOutput works as expected
    tabPanel(title = "tab a", ggvisOutput("plot")),
    tabPanel(title = "tab b", "Static text")
  )
)

server <- function(input, output, session) {
  observe({
    mtcars[1L:input$slider,] %>% ggvis(~mpg, ~hp) %>% layer_points() %>% bind_shiny("plot")
  })
    
  output$text = renderUI({
    paste0("The slider value is ", input$slider)
  })
}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions