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()
})
})
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)