Why would ggplot in shiny app go to rstudio plot window?

I have a shiny app that draw some ggplot2 plots in app. Now I'm making it into a package and export the plot drawing as a function. I found once I draw some ggplot in RStudio and start my shiny app, then all plots in my shiny app went to the RStudio plot pane.

I have tracked down the problem to very specific location and made a minimal working example.

This shiny app draw a ggplot, though it first save the ggplot into png with ggsave, then return the ggplot object to renderPlot so that it is shown in app.

library(shiny)
library(ggplot2)
SAVE_PLOT <- TRUE
ui <- fluidPage(fluidRow(column(12, plotOutput("plot"))))
server <- function(input, output){
  output$plot <- renderPlot({
    g <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
    if (SAVE_PLOT) {
      ggsave("plot.png", g)
    }
    g
  })
}
shinyApp(ui = ui, server = server)

If I run this simple code in RStudio first

library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point()

then run the app above, the plot in app is shown in RStudio plot window.

If I set SAVE_PLOT <- FALSE then the app will have plot shown correctly. This show the problem is caused by ggsave.

I didn't try if plot first and save it later will not have this problem, because the plot in my real app is reactive, plot it first means I need to wrap every plot into a reactive instead of just write in renderPlot.

If I run dev.off after the ggplot in console, the plot will not go to rstudio. This is obviously not a solution.

According to ggsave code,
it create a new device then turn off current device after saving. Is it possible that it actually messed up in this case and turned off the shiny plot device also?

I tried same code in R console instead of RStudio, it has same problem, so it should not be a RStudio problem.

My system info

RStudio 1.1.392

> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Sierra 10.12.2

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

Saving and restoring the current graphic device before/after ggsave seemed to be able solve the problem. Though this is just a workaround.

I tried same code in R console instead of RStudio, it has same problem, so it should not be a RStudio problem.

library(shiny)
library(ggplot2)
SAVE_PLOT <- TRUE
ui <- fluidPage(fluidRow(column(12, plotOutput("plot"))))
server <- function(input, output){
  output$plot <- renderPlot({
    # print.ggplot <- ggplot2:::print.ggplot
    g <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
    if (SAVE_PLOT) {
      cur_dev <- dev.cur()
      ggsave("plot.png", g)
      dev.set(cur_dev)
    }
    g
  })
}
shinyApp(ui = ui, server = server)

Thanks for letting us know about this. Could you file an issue in the Shiny issue tracker?

Issue submitted here.

Though I'm not sure if this is a problem in ggsave side, or some interaction between ggsave and Shiny.