Search code examples
rggplot2shinyshiny-serverggplotly

reactive ggplot tooltip error when nothing in UI selected,


I have this reactive ggplot shiny example using tooltip, problem is that when nothing selected, I got this error > Error : Aesthetics must be either length 1 or the same as the data (1): x, y, colour, label and group When I try this code without plottly and tooltip, then it is working fine. Any idea how to fix this within ggplotly and tooltip ? I posted both version of app.R

app.R (ggplotly version with error when nothing selected)


library(shiny)
library(ggplot2)
library(plotly)

ui <- fluidPage(
  
  sidebarLayout(
    position='right',
    sidebarPanel(
      
      selectInput("region_input", "Select Regions:", 
                  
                  choices = c("Alabama", "Alaska", "Arizona"),
                  selected = "Alabama",
                  multiple = TRUE),
      
    ),
    mainPanel(
      plotlyOutput("distPlot"),
    ))
)

server <- function(input, output) {
  
  data <- structure(list(Region = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("Alabama", "Alaska", "Arizona"), class = "factor"), 
                         date = structure(c(18283, 18284, 18285, 18283, 18284, 18285,18283, 18284, 18285), class = "Date"), 
                         confirmed = c(5L,10L, 7L, 20L, 4L, 1L, 3L, 40L, 8L)), row.names = c(NA, -9L), class = "data.frame")
  
  filtered_data <- reactive( {
    
    
    filtered_data <- data %>%
      filter(Region %in% input$region_input)
    return(filtered_data)
  })
  
  output$distPlot <- renderPlotly({
    ggplotly(
      ggplot(filtered_data(), aes(x = date, y = confirmed, label = Region, color = Region, group = Region, text=paste(date, "\n" , Region, " " ,confirmed  ))) +
        geom_line( aes(date, confirmed, color = Region)),
        tooltip = ("text")
    ) 
    
  })
}

shinyApp(ui = ui, server = server)

app.R working version with ggplot only,without tooltip



library(shiny)
library(ggplot2)


ui <- fluidPage(
  
  sidebarLayout(
    position='right',
    sidebarPanel(
      
      h4(selectInput("region_input", "Select Regions:", 
                     
                     choices = c("Alabama", "Alaska", "Arizona"),
                      selected = "Alabama",
                     multiple = TRUE),
         
      )),
    mainPanel(
      
      
      
      plotOutput("distPlot"),
   
    ))
)

server <- function(input, output) {
  
  data <- structure(list(Region = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("Alabama", "Alaska", "Arizona"), class = "factor"), 
                         date = structure(c(18283, 18284, 18285, 18283, 18284, 18285,18283, 18284, 18285), class = "Date"), 
                         confirmed = c(5L,10L, 7L, 20L, 4L, 1L, 3L, 40L, 8L)), row.names = c(NA, -9L), class = "data.frame")
  
    filtered_data <- reactive( {
      filtered_data <- data %>%
      filter(Region %in% input$region_input)
    return(filtered_data)
  })
  
  output$distPlot <- renderPlot({
    ggplot(filtered_data(), aes(x = date, y = confirmed, label = Region, color = Region, group = Region)) +
      geom_line( aes(date, confirmed, color = Region))

  })
}


shinyApp(ui = ui, server = server)

Dataframe>

> data
   Region       date confirmed
1 Alabama 2020-01-22         5
2 Alabama 2020-01-23        10
3 Alabama 2020-01-24         7
4  Alaska 2020-01-22        20
5  Alaska 2020-01-23         4
6  Alaska 2020-01-24         1
7 Arizona 2020-01-22         3
8 Arizona 2020-01-23        40
9 Arizona 2020-01-24         8

added screenshot error enter image description here


Solution

  • You need to account for NULL when nothing is selected. Try this

    server <- function(input, output) {
      
      data <- structure(list(Region = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("Alabama", "Alaska", "Arizona"), class = "factor"), 
                             date = structure(c(18283, 18284, 18285, 18283, 18284, 18285,18283, 18284, 18285), class = "Date"), 
                             confirmed = c(5L,10L, 7L, 20L, 4L, 1L, 3L, 40L, 8L)), row.names = c(NA, -9L), class = "data.frame")
      
      filtered_data <- reactive( {
        if (is.null(input$region_input)) {
          filtered_data <- NULL
        }else {
          filtered_data <- data %>%
            filter(Region %in% input$region_input)
        }
        
        return(filtered_data)
      })
      
      output$distPlot <- renderPlotly({
        if (!is.null(filtered_data())) {
          ggplotly(
            ggplot(filtered_data(), aes(x = date, y = confirmed, label = Region, color = Region, group = Region, text=paste(date, "\n" , Region, " " ,confirmed  ))) +
              geom_line( aes(date, confirmed, color = Region)),
            tooltip = ("text")
          ) 
        }else return(NULL)
      })
    }
    
    shinyApp(ui = ui, server = server)