ggplot在Shiny应用程序中如何进入RStudio绘图窗口

3
我有一个闪亮的应用程序,绘制一些ggplot2图形。现在我正在将其打包,并将绘图导出为函数。我发现,一旦我在RStudio中绘制了一些ggplot并启动我的闪亮应用程序,那么我的闪亮应用程序中的所有图形都会进入RStudio绘图窗格。
我已经追踪到了问题的非常具体的位置,并制作了一个最小工作示例。
这个闪亮的应用程序绘制了一个ggplot,虽然它首先使用ggsave将ggplot保存为png,然后返回ggplot对象以在应用程序中显示。
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)

如果我先在RStudio中运行这个简单的代码
library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point()

然后运行上面的应用程序,在应用程序中的绘图将显示在RStudio绘图窗口中。
如果我设置SAVE_PLOT <- FALSE,则应用程序会正确显示绘图。这表明问题是由ggsave引起的。
我没有尝试过先绘制图形,然后稍后保存,因为我的实际应用程序中的图形是反应性的,首先绘制它意味着我需要将每个图形包装到一个反应式中,而不仅仅是编写renderPlot。
如果我在控制台中的ggplot之后运行dev.off,则绘图将不会进入rstudio。虽然这显然也不是一个解决方案。
根据ggsave code, 它创建一个新设备,然后在保存后关闭当前设备。在这种情况下,它是否可能真的搞砸了,并关闭了闪亮的绘图设备?
这也可能与Shiny或RStudio有关。
更新:问题不特定于RStudio,R控制台具有相同的问题。

1
问题出在函数ggplot_gtable()上,这个函数是通过print()ggsave()调用的。如果你构建了一个ggplot图形,那么在shiny中可能会出现混乱,我还没有找到解决方法。我写了一些非常烦人的代码这里(第14-25行)来解决这个问题。基本上,我强制要求人们在启动shiny应用程序之前关闭所有图形设备。 - Claus Wilke
感谢确认。我会查看相关代码。它不应该是这样的。 - dracodoc
我已经在ggsave()的bug上提交了一个问题:https://github.com/tidyverse/ggplot2/issues/2363。我怀疑问题不在于`ggplot_gtable()`,而是在于`ggsave()`中设备的打开和关闭。 - wch
@wch 是的,你说得对。我曾经遇到过类似的问题,当时我使用的是 ggplot_gtable() 而不是 ggsave(),但在这种情况下,ggsave() 是罪魁祸首。 - Claus Wilke
2个回答

2

感谢@ Claus Wilke的提示,我认为我们不应该关闭当前设备,而是可以保存设备并恢复它。

我们可以使用以下方法解决问题:

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) {
      cur_dev <- dev.cur()
      ggsave("plot.png", g)
      dev.set(cur_dev)
    }
    g
  })
}
shinyApp(ui = ui, server = server)

感谢@wch,由于这是一个 bug,问题已经在存储库中创建。


谢谢,这似乎是通用的解决方案。它在我的情况下也起作用。 - Claus Wilke

0

ggsave()函数包含在pdf(NULL); ggsave(...); dev.off()中似乎可以提供一种解决方法,但有时在关闭应用程序时图形设备处于奇怪的状态。

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) {
      pdf(NULL)
      ggsave("plot.png", g)
      dev.off()
    }
    g
  })
}
qplot(1:10, 1:10) # shows up in R Studio window
shinyApp(ui = ui, server = server) # shows up in shiny window

是的,设备状态不正确。在此之后,我发现控制台中的新图形将无法绘制到绘图窗口中。 - dracodoc
我发现保存和恢复设备可以解决这个问题。你可以尝试一下,看看它是否能解决你的问题。 - dracodoc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接