firmo23
firmo23

Reputation: 8404

Create a plotly line chart with dynamic number of traces based on shiny widget selection

I have the shiny app below in which I select a country from the widget to visualize in the plot. I would like to be able to select and visualize more than one countries and color the line for each one with a different color every time with the relative legend in the side. Now I cant see the legend and also the different countries selected. Note that the real dataset is bigger than this one, so the number of countries will be bigger.

## app.R ##
library(shiny)
library(shinydashboard)
library(plotly)
library(dplyr)
library(htmlwidgets)
library(shinyWidgets)

df<-structure(list(Year = c(1951, 1951, 1951, 1951, 1951, 1951, 1954, 
                            1954, 1955, 1955, 1957, 1957, 1957, 1957, 1957, 1957, 1958, 1958, 
                            1958, 1958, 1958, 1958, 1960, 1960, 1960, 1960, 1960, 1960, 1960, 
                            1960, 1960, 1960, 1961, 1961, 1962, 1962, 1962, 1962, 1962, 1962, 
                            1962, 1962, 1962, 1963, 1963, 1963, 1963, 1963, 1963, 1963), 
                   Country = c("Belgium", "France", "Germany", "Italy", "Luxembourg", 
                               "Netherlands", "Canada", "Portugal", "France", "Tunisia", 
                               "Belgium", "France", "Germany", "Italy", "Luxembourg", "Netherlands", 
                               "Costa Rica", "El Salvador", "EU", "Guatemala", "Honduras", 
                               "Nicaragua", "Chile", "EFTA", "El Salvador", "Guatemala", 
                               "Honduras", "MERCOSUR", "Mexico", "Nicaragua", "Peru", "Portugal", 
                               "EU", "Greece", "Algeria", "Egypt", "Ghana", "Guinea", "Iraq", 
                               "Jordan", "Mali", "Morocco", "Syria", "Benin", "Burkina Faso", 
                               "Burundi", "Cameroon", "Central African Republic", "Chad", 
                               "Congo - Brazzaville"), Scope = c(4, 4, 4, 4, 4, 4, 3, 3, 
                                                                 5, 5, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 4, 6, 3, 
                                                                 3, 3, 4, 4, 1, 4, 6, 6, 6, 2, 6, 2, 2, 4, 4, 2, 2, 4, 2, 
                                                                 2, 2, 2, 2, 2, 2)), class = c("grouped_df", "tbl_df", "tbl", 
                                                                                               "data.frame"), row.names = c(NA, -50L), groups = structure(list(
                                                                                                 Year = c(1951, 1954, 1955, 1957, 1958, 1960, 1961, 1962, 
                                                                                                          1963), .rows = structure(list(1:6, 7:8, 9:10, 11:16, 17:22, 
                                                                                                                                        23:32, 33:34, 35:43, 44:50), ptype = integer(0), class = c("vctrs_list_of", 
                                                                                                                                                                                                   "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
                                                                                                                                                                                                   ), row.names = c(NA, -9L), .drop = TRUE))


ui <- dashboardPage(title="ScopeDashboard",
                    dashboardHeader(title = span("Scope Dashboard")),
                    
                    dashboardSidebar(
                      selectInput(
                        "cou","Country",choices=c(unique(df$Country)),
                        selected = c(unique(df$Country))[1],
                        multiple = T
                      )
                    ),
                    
                    dashboardBody(
                      plotlyOutput("timetrend")
                      
                    )
)

server <- function(input, output) {
  plot_data <- reactive({
    as.data.frame(
      subset(df, df$Country %in% input$cou)
    ) 
  })
  
  output$timetrend<-renderPlotly({

    fig <- plot_ly(
      data = plot_data(),
      x = ~ Year,
      y = ~ Scope,
      mode = "lines+markers",
      marker = list(
        size = 10,
        color = 'rgba(255, 182, 193, .9)',
        line = list(color = 'rgba(152, 0, 0, .8)',
                    width = 2)
      ),
      text = paste(
        "Year :",
        plot_data()$Year,
        "<br> Count of Scopes :",
        plot_data()$Scope
      ),
      hoverinfo = "text"
    )%>%
      add_trace(
        mode = 'lines+markers') %>% layout(
          title = paste("Count of Scope per country and year",
                        "<br>","-",input$cou,"-"),font=t,
          xaxis = list(
            tickangle=45,
            
            dtick = 2
          ),
          yaxis = list(
            dtick = 1,
            tick0 = 0,
            rangemode = "nonnegative"
            
          )
        )
    
    fig
  })
}

shinyApp(ui, server)   

Upvotes: 1

Views: 520

Answers (1)

SEcker
SEcker

Reputation: 417

You have to use a reactive value for your plot data and pass the country as color to the plotly function. Note, don't use "df" as variable name as you will run into namespace problems

server <- function(input, output) {
  # use reactive value for data frame
  plot_data <- reactive({
    as.data.frame(
      subset(df, df$Country %in% input$cou)
    ) 
  })
  
  output$timetrend<-renderPlotly({
    
    fig <- plot_ly(
      data = plot_data(),
      x = ~ Year,
      y = ~ Scope,
      color = ~Country, # <-------------------- Color according to selected Country
      mode = "lines+markers",
      marker = list(
        size = 10       # <------------------- Remove the color argument 
      ), [...]

Will produce this output enter image description here

Upvotes: 1

Related Questions