在R、RStudio中同时显示并保存绘图

22

我需要将图表保存为.png文件并同时显示图表,而不会重复代码。有没有一种优雅的方法来实现这个目标? 我在MAC上使用RStudio。

我可以按照下面的方式让它工作,但我不喜欢它。

#Step1: save the plot
png("myplot.png")
#plot code
dev.off()

#Step2: to display the plot
#plot code (again!) to display it in RStudio

干杯, I.M.


1
这可能会有所帮助 - https://dev59.com/6msz5IYBdhLWcg3wNE5q#8058665 - 即先绘制图形以显示,然后复制到png。 - thelatemail
4个回答

23

我发现之前的回答不够完整。对如何在默认的RStudio“Plots”窗口中显示图形并同时保存为“png”进行了详细解释。

以防将来有人遇到同样的问题,以下是逐行操作的步骤:

R:> 
R:> dev.list()                  # fresh start. no graphical devices available at this point
NULL
R:> dev.cur()                   # no current device at this point
null device 
      1 
R:> dev.new()                   # open graphical devices
NULL
R:> dev.list()                  # list them
     RStudioGD quartz_off_screen 
        2                 3 
R:> png("plot50.png")           # open an offscreen device as png. New device should be number 4
R:> dev.list()                  # the list of all graphical devices includes the newly created device, number 4
    RStudioGD quartz_off_screen quartz_off_screen 
          2          3               4 
R:> dev.cur()                   # NOTE: the new created device(number 4) becomes "current" automatically,
quartz_off_screen               # as soon as it has been created
            4 
R:> dev.set(which = 2)          # switch back to device 2 used to display the plot in the default RStudio 
                                # "Plots" window
RStudioGD 
    2 
R:> dev.cur()                   # indeed, RstudioGD becomes the current device after the switch step from above
RStudioGD 
    2 
R:> dev.list()                  # just a check on all available devices. device 4 still in the list after 
                                # the switch
    RStudioGD quartz_off_screen quartz_off_screen 
            2           3                 4 
R:> plot(c(1:100))              # plot an example. It will be displayed in "Plots" window of RStudio
R:> dev.list()                  # just a check on all the available devices
   RStudioGD quartz_off_screen quartz_off_screen 
      2                 3                 4 
R:> dev.copy(which = 4)         # copies from current device(RStudioGD) to device 4. It automatically sets
   quartz_off_screen            # device 4 as current
         4 
R:> dev.cur()                   # indeed , device 4 is the current device
  quartz_off_screen 
         4 
R:> dev.off()                   # close device 4. IMPORTANT: AT THIS POINT the plot is saved as
    RStudioGD                   # png("plot50.png") in the current working directory.
                                # Three actions takes place at this point, all at once:
                                # 1. closes device 4
                                # 2. save the plot as "plot50.png"
                                # 3. sets the dev.next() (which is RStudioGD) as the current device
       2 
R:> dev.cur()                   # RStudioGD becomes current as soon as device 4 has been closed down.
   RStudioGD 
       2 
R:> 

设备3出了什么问题?我正在尝试创建一个后置脚本,但R打开了一个png设备,却没有关闭它。它似乎已经成功地写入了指定的ps文件,但我不喜欢这个“png”设备漂浮在那里。 - MichaelChirico
不确定我是否理解了你的问题。你想要在打开新设备时立即关闭设备3吗?如果是这样,答案是你必须手动关闭之前打开的设备。 - flamenco
问题基本上在于通过编号引用设备可能会导致问题——很难跟踪哪个设备在哪个编号。我最终通过使用 which=dev.list()["png"] 及其类似物来解决了这个问题。对于那些使用多个 png 设备的人来说,这可能需要进一步调整,但这是一个开始。 - MichaelChirico

4

补充flamenco的精彩回答,这里提供一个看起来可以在RStudio简单运行的版本。假设您已经在RStudio中绘制了某些内容,然后想要保存相同的内容。

pdf(file = "xyz.pdf")
dev.set(which = 2)
dev.copy(which = 4)
dev.off()

我尝试了反复使用 dev.off(),这个工作流似乎非常稳定。


2
我在这里找到了一个答案:https://statistics.berkeley.edu/computing/saving-plots-r
如果您按照前面的步骤操作,首先必须将图形绘制到屏幕上,然后重新输入命令以将图形保存到文件中。R还提供了dev.copy命令,可以将图形窗口的内容复制到文件中,而无需重新输入命令。对于大多数绘图,情况都很好,但有时将屏幕上的内容转换为不同的格式可能看起来不太好。
要使用此方法,请先按照通常的方式生成图形。当您满意其外观时,调用dev.copy,将所需的驱动程序、要存储它的文件名以及适用于驱动程序的任何其他参数传递给它。
他们使用dev.copy的示例如下:
dev.copy(png,'myplot.png')
dev.off()

0

我在寻找类似问题的研究时偶然发现了这篇文章。我在运行Jupyter笔记本中的R时遇到了保存绘图的麻烦。为了完整起见,我发布了我的解决方案。您可以使用pdf("myplot.pdf")(或pngjpeg等)序列,绘图代码和dev.off()。您必须在Jupyter笔记本的同一单元格中执行所有操作。以下是对我有效的操作(全部在同一单元格中执行)。

pdf("myplot.pdf")
# Plot commands here 
dev.off()

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