In R, I use function savePlot
to save graphs into image files. But my colleague can only open .jpgs and .gifs (probably because he's on vacation, reading emails on his mobile phone). I hate to create jpegs because especially the boxplots looks very ugly (whiskers blurred etc.). But the savePlot
function only supports the following types:
type = c("wmf", "emf", "png", "jpg", "jpeg", "bmp",
"tif", "tiff", "ps", "eps", "pdf")
EDIT: if possible, ideal solution should work without installing ImageMagick (so that the R script is easily portable).
R doesn't have a native GIF graphics driver, mostly (completely?) due to the patent-encumbrances of the GIF format: see http://tolstoy.newcastle.edu.au/R/help/05/02/12809.html .
There is a function in the caTools
package (write.gif()
) but it is specifically designed for writing images. If you wanted to use it you have to do something hacky to convert your plot to an image first (e.g. save as PNG and then read it back into R as an image). For example:
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()
has a lot of stuff about color indexing that I didn't read but that might be important for more complex graphs ...
The animation
package has a saveGIF()
function to save GIFs, but (1) it is designed for saving multi-frame animations (not general graphics), and (2) it does it by calling ImageMagick.
It's easier just to construct that function yourself.
For example:
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
Of course you can either of these in a function if you want to use them regularly.
UPDATE: I spent a while longer on this, to try to get a pure-R solution, but don't yet have a working solution. Suggestions or edits welcome ...
## needs ImageMagick: just for testing ...
showGIF <- function(fn) system(paste("display",fn))
The main function:
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[,1,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],x[,3])
}
if (verbose) cat("creating colour index ...\n")
pp <- paste(P1[,1],P1[,2],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")