Ed_Gravy
Ed_Gravy

Reputation: 2033

R Shiny selected inputs not reacting to renderPlotly

I am making a Shiny app that allows the user to:

  1. Upload a CSV file
  2. Output summary
  3. Select columns/variables to plot

The app almost works to the point where I am able to select the columns from the uploaded CSV, however the selected inputs don't react with renderPlotly as I am getting a blank screen without any errors.

How can I fix this?

Sample data df (from the CSV file):

structure(list(tmean = c(19.601001739502, 17.5659999847412, 22.7600002288818, 
24.0340003967285, 26.2920017242432, 28.0770015716553, 28.5350017547607, 
28.927001953125, 28.2290019989014, 26.9130020141602, 23.1560020446777, 
19.0250015258789, 15.1430006027222, 20.1730003356934, 20.3770008087158, 
24.7090015411377, 26.0360012054443, 28.1920013427734, 28.8940010070801, 
28.3620014190674, 27.7110004425049, 26.7560005187988, 21.7670001983643, 
19.9730014801025, 19.4850006103516, 23.3190002441406, 23.7680015563965, 
25.5580005645752, 25.5420017242432, 27.726001739502, 28.4980010986328, 
28.8360004425049, 28.1360015869141, 25.3380012512207, 24.056001663208, 
21.980001449585), year = c(1980L, 1980L, 1980L, 
1980L, 1980L, 1980L, 1980L, 1980L, 1980L, 1980L, 1980L, 1980L, 
1981L, 1981L, 1981L, 1981L, 1981L, 1981L, 1981L, 1981L, 1981L, 
1981L, 1981L, 1981L, 1982L, 1982L, 1982L, 1982L, 1982L, 1982L, 
1982L, 1982L, 1982L, 1982L, 1982L, 1982L), month = c(1L, 2L, 
3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L, 4L, 5L, 
6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 
9L, 10L, 11L, 12L)), class = "data.frame", row.names = c(NA, 
-36L))

If the entire data is needed it can be accessed here.

Selected Columns:

enter image description here

Code:

library(shiny)
library(tidyverse)  

# Define UI for application that draws an interactive ggplot
options(shiny.maxRequestSize=1024*1024^2)
ui =   navbarPage("Data",
                             tabPanel("Uploading Files",
                                      sidebarLayout(
                                        sidebarPanel(
                                          radioButtons(
                                            "File_Type",
                                            label = "Choose File type",
                                            choices = list(".csv/txt" = 1, ".xlsx" = 2),
                                            selected = 1,
                                            inline = TRUE
                                          ),
                                          
                                          fileInput('file2', 'Upload Your Data',
                                                    accept = c(
                                                      'text/csv',
                                                      'text/comma-separated-values,text/plain',
                                                      '.csv',
                                                      '.xlsx'
                                                    ))),
                                        mainPanel(
                                          verbatimTextOutput("summary")
                                        )
                                        
                                      )),
                             
                             tabPanel("Data Plots",
                                      sidebarLayout(sidebarPanel(
                                        selectInput("x", label = "Select x-axis Variable:",
                                                    choices = NULL),
                                        selectInput("y", label = "Select y-axis Variable: ",
                                                    choices = NULL),
                                        selectInput("color", label =  "Select Grouping variable (optional): ",
                                                    choices = NULL)),
                                        mainPanel(
                                          plotlyOutput("TS")
                                        )))
                  )


# Tell the server how to assemble inputs into outputs
server = function(input, output, session) {
  # Code for uploading an MS-Excel file for plotting
  # Get the uploaded file
  myData = reactive({
    req(input$file2)
    inFile = input$file2
    if (is.null(inFile)) return(NULL)
    data = read.csv(inFile$datapath, header = TRUE)
    data
  })
  
  observe({
    data = myData()
    updateSelectInput(session, 'x', choices = names(data))
  }) 
  
  observe({
    data = myData()
    updateSelectInput(session, 'y', choices = names(data))
  }) 
  
  observe({
    data = myData()
    updateSelectInput(session, 'color', choices = names(data))
  })
  
  output$summary = renderPrint({
    summary(myData())
  })    
  
  # General Timeseries Plot
  output$TS =  renderPlotly({
    req(myData(), input$x, input$y, input$color)
    
    myData() %>% 
      group_by(.data[[input$x]]) %>%
      summarise(AvgTemp = mean(.data[[input$y]])) %>%
      ggplot(aes(x = .data[[input$x]], y = AvgTemp, fill = .data[[input$color]])) +
      geom_line(stat = "identity") +
      xlab("Year") +
      ylab("Temperature (C)") +
      ggtitle("Timeseries Plot By Month")
  })
  
}

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

Upvotes: 1

Views: 187

Answers (1)

YBS
YBS

Reputation: 21349

Try performing data wrangling outside the output$TS.

library(shiny)
library(tidyverse)
library(plotly)

# Define UI for application that draws an interactive ggplot
options(shiny.maxRequestSize=1024*1024^2)
ui =   navbarPage("Data",
                  tabPanel("Uploading Files",
                           sidebarLayout(
                             sidebarPanel(
                               radioButtons(
                                 "File_Type",
                                 label = "Choose File type",
                                 choices = list(".csv/txt" = 1, ".xlsx" = 2),
                                 selected = 1,
                                 inline = TRUE
                               ),

                               fileInput('file2', 'Upload Your Data',
                                         accept = c(
                                           'text/csv',
                                           'text/comma-separated-values,text/plain',
                                           '.csv',
                                           '.xlsx'
                                         ))),
                             mainPanel(
                               verbatimTextOutput("summary")
                             )

                           )),

                  tabPanel("Data Plots",
                           sidebarLayout(sidebarPanel(
                             selectInput("x", label = "Select x-axis Variable:",
                                         choices = NULL),
                             selectInput("y", label = "Select y-axis Variable: ",
                                         choices = NULL),
                             selectInput("color", label =  "Select Grouping variable (optional): ",
                                         choices = NULL)),
                             mainPanel(
                               plotlyOutput("TS")
                             )))
)


# Tell the server how to assemble inputs into outputs
server = function(input, output, session) {
  # Code for uploading an MS-Excel file for plotting
  # Get the uploaded file
  myData = reactive({
    req(input$file2)
    inFile = input$file2
    if (is.null(inFile)) return(NULL)
    data = read.csv(inFile$datapath, header = TRUE)
    data
  })

  observe({
    data = req(myData())
    updateSelectInput(session, 'x', choices = names(data), select=names(data)[2])
    updateSelectInput(session, 'y', choices = names(data), select=names(data)[1])
    updateSelectInput(session, 'color', choices = names(data), select=names(data)[3])
  })

  output$summary = renderPrint({
    summary(myData())
  })

  df1 <- reactive({
    req(myData(),input$x, input$y)
    myData() %>%
      #Calculating mean by year
      group_by(.data[[input$x]]) %>%
      dplyr::summarise(AvgTemp = mean(.data[[input$y]]))
  })

  observe({print(df1())})

  ### General Timeseries Plot
  output$TS =  renderPlotly({
    req(df1(), input$x, input$y, input$color)

    df1() %>%
      ggplot(aes(x = .data[[input$x]], y = AvgTemp)) + ##, color = .data[[input$color]]
      geom_line(stat = "identity") +
      xlab("Year") +
      ylab("Temperature (C)") +
      ggtitle("Timeseries Plot By Year")
  })

}

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

Upvotes: 1

Related Questions