Search code examples
rshinyplotly

I've added a date range slider to my plotly scatterplot in shiny, but how do I get the data to change according to the widget?


I am trying to have the selectinput widget "Years - Slide" change the data used by the graph to the specific date range shown. I was able to connect the axis options in the ui code to the server code since the graph changes, but I do not know how to do the same to the date range widget.

I am trying to use a selectInput widget instead of a date input widget since I only have the year to work with.

Would anyone know how to resolve this?

I was expecting to see the graph according to the changes in the widget, but that is not working.

functional code without selectinput in the server code

library(gapminder)
gm <- gapminder


library(shiny)
library(plotly)
library(tibble)
library(tidyverse)
library(tidyr)
library(readr)
library(dplyr)
library(ggplot2)

# set working directory
setwd("~/BDSWD")


# Define UI ----
ui <- fluidPage(
  column(3,offset = 4, titlePanel("Explore Gapminder Data with Shiny")),
  headerPanel('Graphs'),
  mainPanel(
    plotlyOutput('plot')
  ),
  sidebarPanel(
    #variable selection for x-axis
    selectInput(inputId ='xvrbl', #The input slot that will be used to access the value.
                label = 'X-Axis Variable', #Display label for the control, or NULL for no label.
                choices = colnames(gm), #List of values to select from
                selected = 'lifeExp'
    ),
    
    #variable selection for y-axis
    selectInput(inputId ='yvrbl', #The input slot that will be used to access the value.
                label = 'Y-Axis Variable', #Display label for the control, or NULL for no label.
                choices = colnames(gm), #List of values to select from
                selected = 'gdpPercap'
    ),
    #date range - slider
    sliderInput(inputId = "time",
                label = "Years - Slide",
                min = min(gm$year),
                max = max(gm$year),
                step = 5,
                value = c(min(gm$year),max(gm$year))),
    
  )
)

server <- function(input, output) {
  
  x <- reactive({
    pull(gm[,input$xvrbl])
  })
  
  y <- reactive({
    pull(gm[,input$yvrbl]) #pull used to turn tibble into vctr bc plotly only takes vctrs
  })
  
  
  
  output$plot <- renderPlotly(
    plot1 <- plot_ly(
      x = x(),
      y = y(),
      type = 'scatter',
      mode = 'markers',
      color = gm$continent,
data <- subset(gm,
                     continent %in% input$continents &
                       year >= input$years[1] & year <= input$years[2])
    )
  )
  
}

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

code with my attempt to connect selectInput to the server code (not working)


Solution

  • Unfortunately you code was not working. As first step I added a reactive to create the filtered dataset based on the user input. Second step was to add the selectInput to select the year to be plotted.

    library(gapminder)
    library(shiny)
    library(plotly)
    library(tidyverse)
    
    gm <- gapminder
    
    # Define UI ----
    ui <- fluidPage(
      column(3, offset = 4, titlePanel("Explore Gapminder Data with Shiny")),
      headerPanel("Graphs"),
      mainPanel(
        plotlyOutput("plot")
      ),
      sidebarPanel(
        # variable selection for x-axis
        selectInput(
          inputId = "xvrbl", # The input slot that will be used to access the value.
          label = "X-Axis Variable", # Display label for the control, or NULL for no label.
          choices = colnames(gm), # List of values to select from
          selected = "lifeExp"
        ),
    
        # variable selection for y-axis
        selectInput(
          inputId = "yvrbl", # The input slot that will be used to access the value.
          label = "Y-Axis Variable", # Display label for the control, or NULL for no label.
          choices = colnames(gm), # List of values to select from
          selected = "gdpPercap"
        ),
        # date range - slider
        selectInput(
          inputId = "time",
          label = "Years - Slide",
          choices = unique(gm$year),
          selected = max(gm$year)
        )
      )
    )
    
    server <- function(input, output) {
      x <- reactive({
        dat()[[input$xvrbl]]
      })
    
      y <- reactive({
        dat()[[input$yvrbl]]
      })
    
      dat <- reactive({
        subset(gm, year %in% input$time)
      })
      output$plot <- renderPlotly({
        plot_ly(
          x = x(),
          y = y(),
          type = "scatter",
          mode = "markers",
          color = dat()$continent
        )
      })
    }
    
    # Run the app
    shinyApp(ui = ui, server = server)
    #> 
    #> Listening on http://127.0.0.1:5182