Search code examples
rshinyr-plotly

Multiple line graphs using plotly in shiny R


I'm new to shiny R and Plotly. I'm trying to build a dashboard that has two drop-down boxes and we take input through these dropdown boxes and plot Plotly graphs. All the datasets have time, temp, and weight columns. time goes on the x-axis and for y-axis we can select either temp or weight or maybe both.

  1. the first drop-down takes the input to which dataset to select.

  2. second dropdown box takes the input to select the variable from the dataset selected. Most of the things I have figured out, however, y-axis label does not change dynamically. the label is getting (input$variable) instead of temp or weight.

here is the shiny r output also here is the reproducible example and my code

library(shiny)
library(plotly)
library(DT)

df1 <- data.frame("time" = 1:10, "temp" = c(21,15,31,12,23,45,67,34,54,10), "weight" = c(10,20,30,40,65,35,68,89,100,23), stringsAsFactors = FALSE)
df2 <- data.frame("time" = 1:10, "temp" = c(31,65,31,22,23,45,67,54,54,45), "weight" = c(30,20,40,40,65,85,68,89,14,24), stringsAsFactors = FALSE)





    ui <- fluidPage(

            titlePanel( div(column(width = 5, h2('title here')), )),
            # Input: Selector for choosing dataset
            selectInput(inputId = "dataset",
                        label = "Choose a dataset:",
                        choices = c("df1","df2")),

            selectInput(inputId = "variable",
                        label = "Variable selection", 
                        choices = c("temp","weight"),
                        selected = "weight",
                        multiple = FALSE),
            mainPanel(
                    # Output
                    tabsetPanel(type = "tabs",
                                tabPanel("Plot", plotlyOutput('plot')),
                                tabPanel("Data", DT::dataTableOutput("table")),
                                tabPanel("Key_metrics", DT::dataTableOutput("Key_metrics")))
            )
    )

    server <- function(input, output) {
            dataDf <- reactive({
                    temp <- get(input$dataset)

            })

            output$plot <- renderPlotly(
                    plot_ly(dataDf(), x = ~time, y =~get(input$variable), type = 'scatter', mode = 'lines', name = "temp") %>%
                            add_trace(dataDf(), x = ~time, y = ~weight, type = 'scatter', mode = 'lines',name = "weight") 

            )

            output$table <- DT::renderDataTable({
                    dataDf()
            })
            output$Key_metrics <- DT::renderDataTable({

            })

    }

    shinyApp(ui,server)

Solution

  • You can specify axis labels in layout(). Note that xaxis and yaxis require a list as argument (see here for more details):

    
    output$plot <- renderPlotly(
        plot_ly(dataDf(), x = ~time, y =~get(input$variable), type = 'scatter', mode = 'lines', name = "temp") %>%
          add_trace(dataDf(), x = ~time, y = ~weight, type = 'scatter', mode = 'lines',name = "weight") %>%
          layout(xaxis = list(title = "Time"), yaxis = list(title = input$variable))
    
    )
    

    Edit: following a comment, here's how to plot two lines if two variables are selected and one otherwise (don't forget to put multiple = TRUE in selectInput():

    library(shiny)
    library(plotly)
    library(DT)
    
    df1 <- data.frame("time" = 1:10, "temp" = c(21,15,31,12,23,45,67,34,54,10), "weight" = c(10,20,30,40,65,35,68,89,100,23), stringsAsFactors = FALSE)
    df2 <- data.frame("time" = 1:10, "temp" = c(31,65,31,22,23,45,67,54,54,45), "weight" = c(30,20,40,40,65,85,68,89,14,24), stringsAsFactors = FALSE)
    
    
    
    ui <- fluidPage(
    
      titlePanel( div(column(width = 5, h2('title here')), )),
      # Input: Selector for choosing dataset
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = c("df1","df2")),
    
      selectInput(inputId = "variable",
                  label = "Variable selection", 
                  choices = c("temp","weight"),
                  selected = "weight",
                  multiple = TRUE),
      mainPanel(
        # Output
        tabsetPanel(type = "tabs",
                    tabPanel("Plot", plotlyOutput('plot')),
                    tabPanel("Data", DT::dataTableOutput("table")),
                    tabPanel("Key_metrics", DT::dataTableOutput("Key_metrics")))
      )
    )
    
    server <- function(input, output) {
      dataDf <- reactive({
        temp <- get(input$dataset)
    
      })
    
      output$plot <- renderPlotly({
    
        if (length(input$variable) > 1){
          plot_ly(dataDf(), x = ~time, y =~get(input$variable[1]), 
                  type = 'scatter', mode = 'lines', name = "temp") %>%
            add_trace(dataDf(), x = ~time, y = ~get(input$variable[2]), 
                      type = 'scatter', mode = 'lines',name = "weight") %>%
            layout(xaxis = list(title = "Time"))
        }
        else {
          plot_ly(dataDf(), x = ~time, y =~get(input$variable[1]), type = 'scatter', mode = 'lines', name = "temp") %>%
            add_trace(dataDf(), x = ~time, y = ~get(input$variable[1]), type = 'scatter', mode = 'lines',name = "weight") %>%
            layout(xaxis = list(title = "Time"), yaxis = list(title = input$variable))
        }
    
      })
    
      output$table <- DT::renderDataTable({
        dataDf()
      })
      output$Key_metrics <- DT::renderDataTable({
    
      })
    
    }
    
    shinyApp(ui,server)
    

    Put what you want as y-axis label based on the original answer. Note that this answer only works if there are two choices.