Saving plots in R as GIFs
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.
- install ImageMagick (http://imagemagick.org)
- save as a PNG, then use ImageMagick to convert.
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")
Related videos on Youtube
Tomas
Updated on September 24, 2022Comments
-
Tomas over 1 year
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 thesavePlot
function only supports the following types:type = c("wmf", "emf", "png", "jpg", "jpeg", "bmp", "tif", "tiff", "ps", "eps", "pdf")
How can I save plot in GIF in R?
EDIT: if possible, ideal solution should work without installing ImageMagick (so that the R script is easily portable).
-
user1981275 over 10 yearsPackages
animation
andcaTools
have functions to save gifs: see cran.r-project.org/web/packages/animation/animation.pdf and svitsrv25.epfl.ch/R-doc/library/caTools/html/GIF.html. See also here: tolstoy.newcastle.edu.au/R/help/05/02/12809.html -
Ben Bolker over 10 yearsif you can install ImageMagick imagemagick.org you can save as PNG and
convert myPlot.png myPlot.gif
from the command line, orsystem("convert myPlot.png myPlot.gif")
from within R -
Ben Bolker over 10 yearsAre you sure your colleague can only read GIFs, and not PNGs? Maybe you could try saving as PNG and sending them a test example ...
-
-
Tomas over 10 yearsThank you Ben! I would like a solution that would work without installing ImageMagick (so that the R script is easily portable), but the first solution with
write.gif
does not work. It produces animated greyscale (!) gif. Seems that thewrite.gif
function is not able to produce optimal palette (i.e. doesn't have the color clustering algorithm to create optimal 256 colour palette). -
Ben Bolker over 10 yearsit looks like
write.gif
may have some more options -- did you tryscale="never"
? It certainly doesn't seem to have colour clustering algorithm, but a relatively simple graphic might not need one ...