在循环中保存R绘图

7

昨天我将R升级到3.0.0版本,将ggplot2升级到0.9.3.1版本(并对脚本进行了一些小改动)。现在,当我尝试保存图像时,出现了错误-不幸的是,这个错误无法通过较小的数据框来重现,因此我包含了一个生成相同大小的代码。

library("ggplot2")

# Create data frame
# Time interval ID (x)
bin.ts.avg <- as.data.frame(rep(1:18, 31))
names(bin.ts.avg) <- "x"
# Time (sequence of 10 minuter intervals between 7am and 10am)
tt.month.bins <- seq(from=as.POSIXct("2012-01-01 GMT"), to=as.POSIXct("2012-01-01 GMT") + 60*60*24*31, by="10 mins")
tt.month.bins <- tt.month.bins[-length(tt.month.bins)]
temp <- as.numeric(format(tt.month.bins, "%H"))
ind <- which(temp >=7 & temp <= 9)  
tt.month.bins <- tt.month.bins[ind]
bin.ts.avg$dep <- tt.month.bins
# Value (with some NA)
bin.ts.avg$tt <- runif(558, min=2.5, max=5)
bin.ts.avg$tt[trunc(runif(200, min=1, max=558))] <- NA
# Day
bin.ts.avg$depday <- rep(1:31, each=18)

for (i in 1:2){
  if (1){
    hist(rnorm(100))
    dev.print(file="MyHist.png",device=png, bg="white",  width=640, height=352) 

    p <- ggplot(bin.ts.avg, aes(x, tt)) + geom_point() +geom_line() + facet_grid(.~depday)
    p <- p + ggtitle("10 minute averages")+ xlab("Hour") + ylab("Values")    
    p <- p + scale_x_continuous(breaks=c(min(bin.ts.avg$x), max(bin.ts.avg$x)), labels=c("7", "10"))
    print(p)  
    dev.print(file="MyGGPlot.png",device=png, bg="white",  width=640, height=352) 
  }
}

运行此脚本时,我收到以下错误消息:

Error in UseMethod("depth") : no applicable method for 'depth' applied to an object of class "NULL"

然而,如果我逐行运行脚本,一切都正常(如下图所示)。 How the ggplot should look 现在,如果我更改for循环并使用dev.copy和ggsave而不是dev.print,如下所示:
for (i in 1:2){
  if (1){
    hist(rnorm(100))
    dev.copy(file="MyHist.png",device=png, bg="white",  width=640, height=352) 
    dev.off()

    p <- ggplot(bin.ts.avg, aes(x, tt)) + geom_point() +geom_line() + facet_grid(.~depday)
    p <- p + ggtitle("10 minute averages")+ xlab("Hour") + ylab("Values")    
    p <- p + scale_x_continuous(breaks=c(min(bin.ts.avg$x), max(bin.ts.avg$x)), labels=c("7", "10"))
    print(p)  
    ggsave(filename="MyGGPlot.png")
  }
}

当我尝试使用画图打开“MyGGPlot.png”时,我收到一个错误消息,指出:
A sharing violation occurred while accessing <filename>

我正在使用RStudio版本0.97.449运行脚本。 有什么建议可以让我保存当前的图表吗?


在每个循环中,尝试打开一个设备(例如 png()),并在绘图之前给出一个唯一的文件名。然后在循环结束时使用 dev.off() 关闭该设备。 - Marc in the box
1个回答

12

有几点需要注意:

dev.copy之后使用graphics.off(),这将关闭所有图形设备。你也可以调用dev.off()两次(但是graphics.off()是一个包装器,基本上会调用足够多次的dev.off()来关闭所有图形设备)。

ggsave不需要打印对象(这不是FAQ 7.22相关的情况)。

默认值是last_plot的值,它是创建、修改或打印的最后一个ggplot对象。因此,创建p对于ggsave('filname.png')来保存该对象就足够了。

for (i in 1:2){
  if (1){
    hist(rnorm(100))
    dev.copy(file="MyHist.png",device=png, bg="white",  width=640, height=352) 
    graphics.off()

    p <- ggplot(bin.ts.avg, aes(x, tt)) + geom_point() +geom_line() + facet_grid(.~depday)
    p <- p + ggtitle("10 minute averages")+ xlab("Hour") + ylab("Values")    
    p <- p + scale_x_continuous(breaks=c(min(bin.ts.avg$x), max(bin.ts.avg$x)), labels=c("7", "10"))
   # no need to print p
   ggsave(filename="MyGGPlot.png")
   # note specifying p is redundant but explicit.
   # ggsave(filename = 'MyGGplot.png', plot = p)
  }
}

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