Duck
Duck

Reputation: 39595

How to display plotly visualizations into shiny app

I am trying to build a shiny app to track details about Covid 19 spread in two countries. I am using shiny to set all content and plotly to include dynamic and interactive graphics. I have figured out some possible solutions to this problem but I am not sure what it is happening. The dataframe I am using is df2 whose dput version I include in the final side of this post.

Everything looks fine in the app, with filtered the input for the plotly visualization but in the end when I compile the app I got this error:

Listening on http://127.0.0.1:3082
Warning: Error in : Result must have length , not 0

This is the code for my app:

#Shiny app design
library(shiny)
library(ggplot2)
library(dplyr)
library(httr)
library(reshape2)
library(tidyr)
library(stringr)
library(plotly)
# Set colors
confirmed_color <- "purple"
active_color <- "#1f77b4"
recovered_color <- "forestgreen"
death_color <- "red"
#Data put here dput version of df2
df2 <- ...
#App design
#ui design
ui <- fluidPage(titlePanel("Corona Virus Tracker"),
                sidebarLayout(
                  sidebarPanel("Choose your country",
                               uiOutput("countryOutput")),
                  mainPanel(plotOutput("coolplot"))
                ))

#server design
server <- function(input, output) {
  output$countryOutput <- renderUI({
    selectInput("countryInput", "Country",
                sort(unique(df2$country)),
                selected = "Albania")
  })
  filtered <- reactive({

    filtered <- df2 %>%
      filter(country == input$countryInput)
    filtered <- as.data.frame(filtered)
  })

  output$coolplot <- renderPlotly({
    #First plot design
    plotly::plot_ly(data = filtered()) %>%
      plotly::add_trace(
        x = ~Date,
        # y = ~active_cum,
        y = ~confirmed_cum,
        type = "scatter",
        mode = "lines+markers",
        # name = "Active",
        name = "Confirmed",
        line = list(color = active_color),
        marker = list(color = active_color)
      ) %>%
      plotly::add_trace(
        x = ~Date,
        y = ~death_cum,
        type = "scatter",
        mode = "lines+markers",
        name = "Death",
        line = list(color = death_color),
        marker = list(color = death_color)
      ) %>%
      plotly::layout(
        title = "",
        yaxis = list(title = "Cumulative number of cases"),
        xaxis = list(title = "Date"),
        legend = list(x = 0.1, y = 0.9),
        hovermode = "compare"
      )


  })
}
shinyApp(ui = ui, server = server)

The dput version of my data df2 is next:

df2 <- structure(list(Date = structure(c(18316, 18317, 18318, 18319, 
18320, 18321, 18322, 18323, 18324, 18325, 18326, 18327, 18328, 
18329, 18330, 18331, 18332, 18333, 18334, 18335, 18336, 18337, 
18338, 18339, 18340, 18341, 18342, 18343, 18344, 18345, 18346, 
18347, 18348, 18330, 18331, 18332, 18333, 18334, 18335, 18336, 
18337, 18338, 18339, 18340, 18341, 18342, 18343, 18344, 18345, 
18346, 18347, 18348), class = "Date"), confirmed = c(1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 5L, 7L, 7L, 
7L, 11L, 16L, 21L, 22L, 22L, 22L, 24L, 24L, 40L, 40L, 74L, 84L, 
94L, 110L, 2L, 10L, 12L, 23L, 33L, 38L, 42L, 51L, 55L, 59L, 64L, 
70L, 76L, 89L, 104L, 123L, 146L, 174L, 186L), deaths = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 2L, 4L, 4L, 
0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 4L, 5L, 
5L, 6L, 8L), recovered = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 2L, 2L, 2L, 10L, 17L, 17L, 31L), unrecovered = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 5L, 7L, 
7L, 7L, 11L, 16L, 21L, 22L, 22L, 22L, 24L, 24L, 39L, 39L, 73L, 
82L, 90L, 106L, 2L, 10L, 11L, 22L, 32L, 37L, 41L, 50L, 54L, 57L, 
62L, 68L, 74L, 87L, 100L, 118L, 141L, 168L, 178L), country = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L), .Label = c("Afghanistan", "Albania"), class = "factor"), 
    active = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 4L, 4L, 5L, 7L, 7L, 7L, 11L, 16L, 21L, 22L, 22L, 22L, 
    24L, 24L, 39L, 39L, 73L, 82L, 90L, 106L, 2L, 10L, 11L, 22L, 
    32L, 37L, 41L, 50L, 54L, 57L, 62L, 68L, 74L, 87L, 100L, 118L, 
    141L, 168L, 178L), confirmed_cum = c(1L, 2L, 3L, 4L, 5L, 
    6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 17L, 21L, 26L, 33L, 40L, 
    47L, 58L, 74L, 95L, 117L, 139L, 161L, 185L, 209L, 249L, 289L, 
    363L, 447L, 541L, 651L, 2L, 12L, 24L, 47L, 80L, 118L, 160L, 
    211L, 266L, 325L, 389L, 459L, 535L, 624L, 728L, 851L, 997L, 
    1171L, 1357L), death_cum = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 1L, 2L, 3L, 5L, 9L, 13L, 0L, 0L, 1L, 
    2L, 3L, 4L, 5L, 6L, 7L, 9L, 11L, 13L, 15L, 17L, 21L, 26L, 
    31L, 37L, 45L), active_cum = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
    8L, 9L, 10L, 11L, 12L, 13L, 17L, 21L, 26L, 33L, 40L, 47L, 
    58L, 74L, 95L, 117L, 139L, 161L, 185L, 209L, 248L, 287L, 
    360L, 442L, 532L, 638L, 2L, 12L, 23L, 45L, 77L, 114L, 155L, 
    205L, 259L, 316L, 378L, 446L, 520L, 607L, 707L, 825L, 966L, 
    1134L, 1312L)), row.names = c(NA, 52L), class = "data.frame")

Many thanks for your help!

Upvotes: 1

Views: 128

Answers (2)

Georgi Petkov
Georgi Petkov

Reputation: 46

I believe you don't have a default option for the filter so when you run the app it tries to pass an empty data frame. You could use if statement to check if input$countryInput has a value and if not what should happen. The added 2 lines resolve the error for me. I hope this helps. enter image description here

Upvotes: 0

nurandi
nurandi

Reputation: 1618

Change

mainPanel(plotOutput("coolplot"))

to

mainPanel(plotlyOutput("coolplot"))

Result

plotly

As Ben suggestion, you might also change

filter(country == input$countryInput)

to

filter(country == req(input$countryInput))

Upvotes: 2

Related Questions