Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving plots in R as GIFs

Tags:

plot

r

image

gif

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")

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).

like image 384
Tomas Avatar asked Aug 19 '13 15:08

Tomas


People also ask

How do I Export plots in R?

Plots panel –> Export –> Save as Image or Save as PDF It's also possible to save the graph using R codes as follow: Specify files to save your image using a function such as jpeg(), png(), svg() or pdf(). Additional argument indicating the width and the height of the image can be also used.

How do I save graphics to an image in R?

In R GUI you will need to go to File → Save as and select the type of file you prefer. If you select Jpeg , you can also specify the quality of the resulting image. The last option is copying the image to the Clipboard.

How do you save a Plotly animation?

A plotly animation cannot be saved, directly, but there are two methods to create a video or a gif file from frames. The first method is the poor man method: It consists in updating your figure (the base figure) with the corresponding properties/attributes that usually are inserted in each go.


1 Answers

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")
like image 145
Ben Bolker Avatar answered Oct 12 '22 09:10

Ben Bolker