0
votes

When I select options in my Shiny application, I expect it to produce a graph in plotly and it does. It look like this: enter image description here

When I unselect the options, it SHOULD look like this:

enter image description here

However, the output is misbehaving in a way I don't understand why. This is output I get:

enter image description here As you can see, the x and y axis still remains. If I hover over the plot with no options selected, the plot still shows the coordinates. Here is my code:

# UI
box(width = NULL, uiOutput("plotTitle"),
plotlyOutput('plot1', height="730px"), collapsed = F, title = "Figure",
status = "warning", solidHeader = T, height = "830px")

# SERVER
output$plot1 <- renderPlotly({
   validate(
      need(input$crops, "INSTRUCTIONS: \n\n1) Select Crops Of Interest.\n2) 
        Use 'Farm' tab to refine results.\n3) Hover over graph to see values.")
   )

crop.data <- reactive({
crop.list <- input$crops
z.df <- dat
c.df <- subset(z.df, Crop %in% crop.list)
c.df <- unique(c.df)
})



output$plotTitle <- renderUI({
  if(length(crop.data()) > 0) {
    div(style='background-color:green; color:white; text-align:center; 
          font-size:22px; font-family:"Open Sans",verdana,arial,sans-serif', 
        input$metric)
  }
})

# s.df is the Dataframe
s.df <- subset(s.df, Crop %in% input$crops)

if(length(crop.data()) > 0) {

  if(input$metric == "Percentage") {
    p <- plot_ly(s.df, x = ~Farm, y = ~Percentage, color = ~Crop) %>% 
      layout(barmode = 'stack', xaxis = list(title = ''), margin = list(b = 140))

  } else if(input$metric == "Acreage") {
    p <- plot_ly(s.df, x = ~Farm, y = ~Acreage, color = ~Crop) %>% 
       layout(barmode = 'stack', xaxis = list(title = ''), margin = list(b = 140))

  } else {
    p <- plot_ly(s.df, x = ~Farm, y = ~Exposure_Costs, color = ~Crop) %>% 
      layout(barmode = 'stack', xaxis = list(title = ''), 
              yaxis = list(title = 'Exposure Costs'), margin = list(b = 140))
  }
  p
}
})

Is there a specific reason as to why this happens? Also, this error doesn't exist on my local instance but occurs on the shiny server and another's local instance. How do I fix it?

1
Try to provide a minimum working example (including dataset). I'd suggest you avoid defining a reactive within another reactive ie. output$plotTitle and crop.data should be defined outside of the call to renderPlotly - HubertL

1 Answers

0
votes

You're using length(crop.data()) to check whether or not to plot but this will return a value greater than 0 for an "empty" data.frame because it is counting the number of columns.

e.g.

> (x <- iris[0, ])
[1] Sepal.Length Sepal.Width  Petal.Length Petal.Width  Species     
<0 rows> (or 0-length row.names)
> length(x)
[1] 5

You really should untangle your mangling of the reactives, renderUI and renderPlotly but replacing length(crop.data()) with nrow(crop.data()) should solve your problem.

This reproducible example shows that your desired behavior does occur for a simple example:

library("shiny")
library("plotly")

set.seed(100)
d <- diamonds[sample(nrow(diamonds), 1000), ]


ui <- fluidPage(

   titlePanel("Null Plotly Object"),

   sidebarLayout(
      sidebarPanel(
         checkboxGroupInput("cuts", "Cut", choices = sort(unique(d$cut)))
      ),

      mainPanel(
         plotlyOutput("distPlot")
      )
   )
)

server <- function(input, output) {

  plot_dat <- reactive({
    shiny::validate(
      need(input$cuts, "Select a cut")
    )
    d[d$cut %in% input$cuts, ]
  })

   output$distPlot <- renderPlotly({
     plot_ly(plot_dat(), x = ~carat, y = ~price, color = ~carat, type = "scatter",
             mode = "markers", size = ~carat, text = ~paste("Clarity: ", clarity))
   })
}

shinyApp(ui = ui, server = server)