Search code examples
rshinyr-plotlypheatmap

Shiny - plotlyoutput stops plotoutput from working


I am experiencing a weird error. I don't know if it is because of Shiny, or pheatmap, or RStudio, or plotly.

I need to show a plot coming from pheatmap and another plot (with renderPlotly) in the same Shiny app. The two must be on different navBars and they need to show up only when I press a button.

If I plot the pheatmap, then plot the plotly graph, then go back to the heatmap, the heatmap disappears as soon as I press the button that should generate it.

Also, the map does not work anymore for the next runs (see comment about graphic devices below).

This doesn't happen if I use a normal plotOutput for the graph, instead of plotlyOutput (and renderPlotly).

However, now the map is plot on the "Plots" panels of RStudio.

While debugging, I noticed that when using plotlyOutout, there are rogue graphic devices around. E.g., when using plotOutput, using a breakpoint at plot(map_reactive) in server.R, dev.list() shows "NULL".
At the same breakpoint, when using plotlyOutput, dev.list() shows:

Browse[2]> dev.list()
    RStudioGD quartz_off_screen quartz_off_screen 
            2                 3                 4 

Turning the devices off with dev.off() doesn't help during debug (I don't fully know how debugging scoping works), but if I do that after stopping the app, everything works again.

This is the code:

UI:

# ui.R

library(shiny)
library(plotly)

shinyUI(
  navbarPage("Test",
             selected = 'map',
    tabPanel('map', 
             sidebarLayout(
      sidebarPanel('side',
                   actionButton('getHmap', 'get heatmap')
                   ),
      mainPanel('main',
                plotOutput("themap")
                )
    )),
    tabPanel('plot', 
             sidebarLayout(
               sidebarPanel('side',
                            actionButton('getPlot', 'getPlot')
               ),
               mainPanel('main',
                         plotlyOutput("theplot")
               )
             ))
  )

)

Server:

# server.R

library(shiny)
library(pheatmap)

shinyServer(
  function(input, output, session) {

    map_reactive = eventReactive(input$getHmap,{
      tmp = data.frame(matrix(1:20,5,4))
      tmpmap = pheatmap(tmp, silent = T)
      tmpmap$gtable
    })

    output$themap = renderPlot({
      plot(map_reactive())
    })

    plot_reactive = eventReactive(input$getPlot,{
      return(ggplot(data.table(x=1:10, y=1:10), aes(x=x,y=y))+
               geom_point()
             )
    })

    output$theplot = renderPlotly({
      plot_reactive()
    })

})

Solution

  • This seems to be working for me:

     ui = navbarPage("Test",
                    selected = 'map',
                    tabPanel('map', 
                             sidebarLayout(
                               sidebarPanel('side',
                                            actionButton('getHmap', 'get heatmap')
                               ),
                               mainPanel('main',
                                         plotOutput("themap")
                               )
                             )),
                    tabPanel('plot', 
                             sidebarLayout(
                               sidebarPanel('side',
                                            actionButton('getPlot', 'getPlot')
                               ),
                               mainPanel('main',
                                         plotlyOutput("theplot")
                               )
                             ))
    )
    
    server = function(input, output, session) {
    
      observeEvent(input$getHmap, {
    
        tmp = data.frame(matrix(1:20,5,4))
        tmpmap = pheatmap(tmp, silent = T)
    
      output$themap = renderPlot({        
        tmpmap
      })
    
      })
    
      plot_reactive = eventReactive(input$getPlot,{
        return(ggplot(data.table(x=1:10, y=1:10), aes(x=x,y=y))+
                 geom_point()
        )
      })
    
      output$theplot = renderPlotly({
        plot_reactive()
      })     
    }
    
    shinyApp(ui, server)