在R中,我使用函数savePlot将图形保存到图像文件中.但我的同事只能打开.jpgs和.gifs(可能是因为他正在度假,在手机上阅读电子邮件).我讨厌创造jpegs,因为特别是箱形图看起来非常难看(胡须模糊等).但savePlot函数仅支持以下类型:
type = c("wmf","emf","png","jpg","jpeg","bmp","tif","tiff","ps","eps","pdf")
如何在R中保存GIF中的情节?
编辑:如果可能的话,理想的解决方案应该可以在不安装ImageMagick的情况下工作(这样R脚本很容易移植).
解决方法
R没有原生的GIF图形驱动程序,大部分(完全?)由于GIF格式的专利保留:见
http://tolstoy.newcastle.edu.au/R/help/05/02/12809.html.
caTools包中有一个函数(write.gif()),但它专门用于编写图像.如果你想使用它,你必须先做一些hacky将你的绘图转换为图像(例如保存为PNG,然后将其作为图像读回R).例如:
png("myPlot.png") plot(rnorm(1000),rnorm(1000)) dev.off() library(png) P1 <- readpnG("myPlot.png") library(caTools) write.gif(P1,"myPlot.gif") showGIF <- function(fn) system(paste("display",fn)) showGIF("myPlot.gif") unlink("myPlot.gif") ## clean up
?write.gif()有很多关于颜色索引的东西,我没有阅读,但这对于更复杂的图形可能很重要……
动画包有一个saveGIF()函数来保存GIF,但(1)它用于保存多帧动画(不是通用图形),(2)它通过调用ImageMagick来实现.
只是自己构建这个功能更容易.
>安装ImageMagick(http://imagemagick.org)
>另存为PNG,然后使用ImageMagick进行转换.
例如:
png("myPlot.png") plot(rnorm(1000),rnorm(1000)) dev.off() system("convert myPlot.png myPlot.gif") unlink("myPlot.png") ## clean up showGIF("myPlot.gif") unlink("myPlot.gif") ## clean up
当然,如果你想定期使用它们,你可以在函数中使用其中任何一个.
更新:我花了一些时间来尝试获得纯R解决方案,但还没有一个有效的解决方案.建议或编辑欢迎……
## needs ImageMagick: just for testing ... showGIF <- function(fn) system(paste("display",fn))
主要功能:
saveGIF <- function(fn,verbose=FALSE,debug=FALSE) { require(png) require(caTools) tmpfn <- tempfile() on.exit(unlink(tmpfn)) savePlot(tmpfn,type="png") P1 <- readpnG(tmpfn) dd <- dim(P1) P1 <- aperm(P1,c(3,1,2),resize=TRUE) ## P1[,15] dim(P1) <- c(dd[3],prod(dd[1:2])) P1 <- t(P1) if (verbose) cat("finding unique colours ...\n") P1u <- unique(P1) rgbMat <- function(x) { rgb(x[,1],x[,2],3]) } if (verbose) cat("creating colour index ...\n") pp <- paste(P1[,P1[,3],sep=".") ## make sure factor is correctly ordered ind <- as.numeric(factor(pp,levels=unique(pp))) if (verbose) cat("finding colour palette ...\n") if (nrow(P1u)>256) { if (verbose) cat("kmeans clustering ...\n") kk <- kmeans(P1u,centers=256) ind <- kk$cluster[ind] pal <- rgbMat(kk$centers) } else { pal <- rgbMat(P1u) } ## test: if (debug) { dev.new() par(mar=rep(0,4)) image(t(matrix(ind-1,nrow=dd[1])),col=pal,axes=FALSE,ann=FALSE) } if (verbose) cat("writing GIF ...\n") indmat <- matrix(ind-1,nrow=dd[1]) storage.mode(indmat) <- "integer" write.gif(indmat,fn,col=as.list(pal),scale="never") } X11.options(antialias="none") image(matrix(1:64,nrow=8),col=rainbow(10)) saveGIF("tmp.gif",verbose=TRUE,debug=TRUE) showGIF("tmp.gif")