Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When showing a ggplot in a shiny app, how do I capture the ggplot warning that appears in the console, and display in the app?

Tags:

r

ggplot2

shiny

I have a simple app, below, that displays a ggplot. ggplot generates a warning in the console (see picture at bottom). I'd like to capture the warning, and display it in the app, under the plot.

Here's my code:

library(shiny)
library(ggplot2)

ui <- fluidPage(

   titlePanel("How do i output ggplot warnings? :("),
   mainPanel(
       plotOutput("my_plot_that_generates_warnings"),
       tags$br(),
       verbatimTextOutput(outputId='ggplot_warnings')
   )
)

server <- function(input, output) {

    messages <- reactiveValues(ggplot_warning = 'How to capture warning and display it?')
    output$my_plot_that_generates_warnings <- renderPlot({
        tryCatch({

            ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) +
                geom_point() +
                geom_smooth()

        }, message = function(e) {
            messages$ggplot_warning <- e$message
        }, warning = function(e) {
            messages$ggplot_warning <- e$message
        }, error = function(e) {
            messages$ggplot_warning <- e$message
        })
    })

    output$ggplot_warnings <- renderPrint({
        cat(messages$ggplot_warning)
    })
}

shinyApp(ui = ui, server = server)

I assume the underlying problem has to do with lazy evaluation and the fact that the graph doesn't actually get rendered (and the warning generated) until after the trycatch. I can actually get the warning to appear in the verbatimTextOutput by wrapping ggplot call in a print(), but then of course the plot doesn't show up.

In my ignorance of the problem I've tried force() rather than print() but it didn't work.

enter image description here

like image 421
shaneker Avatar asked Nov 29 '18 08:11

shaneker


1 Answers

When you call ggplot it creates an object of type ggplot, as far as my understanding goes, internally, the messages aren't generated till you call print() on the object. There's an explanation on similar issue wrt messages so have a read Why does ggplot not allow suppressing of messages generated by its geoms?.

What we can do is explicitly print the ggplot and capture the messages

library(shiny)
library(ggplot2)

ui <- fluidPage(

  titlePanel("This is now fixed :)"),
  mainPanel(
    plotOutput("my_plot_that_generates_warnings"),
    tags$br(),
    verbatimTextOutput(outputId='ggplot_warnings')
  )
)

server <- function(input, output) {

  data <- reactive({
    ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) +
      geom_point() +
      geom_smooth()
  })

  dataerrors <- reactive({
    tryCatch({
      print(data())
    }, message = function(e) {
      return(e$message)
    }, warning = function(e) {
      return(e$message)
    }, error = function(e) {
      return(e$message)
    })
  })

  output$my_plot_that_generates_warnings <- renderPlot({
    data()
  })

  output$ggplot_warnings <- renderPrint({
    dataerrors()
  })
}

shinyApp(ui = ui, server = server)

enter image description here

like image 170
Pork Chop Avatar answered Sep 29 '22 13:09

Pork Chop