LoF10 LoF10 - 4 months ago 30
R Question

ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

working on integrating plotly into shiny dashboard and ran into an error when using conditional statements. I'm trying to switch through charts using an 'if' statement with selectInput. I've used this with the circlize package and ggplot graphs without issue but when trying to use it with plotly I get the following error:

Error in UseMethod: no applicable method for 'plotly_build' applied to an object of class "NULL"

I found a posting here with similar issues, but not exactly answering my specific question:

Convert ggplot object to plotly in shiny application

Here is a sample using a similar code to the one used in the posting above but with modifications to show what I'm looking to do and the error that keeps popping up:

library(shiny)
library(ggplot2)
library(ggthemes)
library(plotly)
ui = dashboardPage(
dashboardHeader(title = 'sample') ,
dashboardSidebar(),
## Body content
dashboardBody(
fluidRow(
box(background="green", selectInput(inputId = "dimension", label = strong("Choose Metric"),
choices = c('choice'='1','choice2'='2'),
multiple = FALSE, selectize = TRUE)),

box(plotlyOutput(outputId = 'plot2')))
))

server <- function(input, output) {

output$plot2 <- renderPlotly({
print(
ggplotly(
ggplot(data = mtcars, aes(x = disp, y = cyl)) + geom_smooth(method =
lm, formula = y~x) + geom_point() + theme_gdocs()))

if(input$dimension == '2') {
print(
ggplotly(
ggplot(data = mtcars, aes(x = hp, y = cyl)) + geom_smooth(method =
lm, formula = y~x) + geom_point() + theme_gdocs()))

}
})
}

shinyApp(ui, server)


I'm still learning so I'm sure this a simple error that escapes me but I am unsure what it might be. Appreciate the help!

Answer

Shortly, the problem was that if input$dimension was '1' there was no return value. You were printing the plot out but R went then one step further and checked if the condition was met. There are few ways to code it correctly.

You can save the plot in the object, say res, and if the condition is met, overwrite it with a new plot and finally return it at the end of the function - see the example below. You could also use the else statement.

library(shiny)
library(shinydashboard)
library(ggplot2)
library(ggthemes)
library(plotly)

ui = dashboardPage(
  dashboardHeader(title = 'sample') ,
  dashboardSidebar(),
  ## Body content
  dashboardBody(
    fluidRow(
      box(background="green", selectInput(inputId = "dimension", 
                                          label = strong("Choose Metric"),
                                          choices = c('choice'='1','choice2'='2'), 
                                          multiple = FALSE, selectize = TRUE)),

      box(plotlyOutput(outputId = 'plot2')))
  ))

server <- function(input, output) {

  output$plot2 <- renderPlotly({

    res <- ggplotly(
              ggplot(data = mtcars, aes(x = disp, y = cyl)) + 
                geom_smooth(method = lm, formula = y ~ x) + 
                geom_point() + 
                theme_gdocs())


    if (input$dimension == '2') {

      res <- ggplotly(
                ggplot(data = mtcars, aes(x = hp, y = cyl)) +  
                  geom_smooth(method = lm, formula = y ~ x) + 
                  geom_point() + 
                  theme_gdocs())
    }
    res
  })
}

shinyApp(ui, server)
Comments