yihui / animation

A gallery of animations in statistics and utilities to create animations
https://yihui.org/animation/
206 stars 60 forks source link

bug when ani.dev is a function #120

Closed stla closed 5 years ago

stla commented 5 years ago

Hello,

If the option ani.dev is set to a function then there's a bug in saveGIF:

> saveGIF
function (expr, movie.name = "animation.gif", img.name = "Rplot", 
    convert = "magick", cmd.fun, clean = TRUE, extra.opts = "", 
    ...) 
{
    oopt = ani.options(...)
    on.exit(ani.options(oopt))
    if (!dir.exists(dirname(movie.name))) {
        dir.create(dirname(movie.name))
    }
    owd = setwd(tempdir())
    on.exit(setwd(owd), add = TRUE)
    file.ext = ani.options("ani.type")
    unlink(paste(img.name, "*.", file.ext, sep = ""))
    ani.dev = ani.options("ani.dev")
    if (is.character(ani.dev)) 
        ani.dev = get(ani.dev)
    img.fmt = paste(img.name, ani.options("imgnfmt"), ".", file.ext, 
        sep = "")
    if ((use.dev <- ani.options("use.dev"))) {
        if (any(grepl(ani.options("ani.dev"), c("png", "bmp", 
            "jpeg", "tiff")))) {
            ani.dev(file.path(tempdir(), img.fmt), width = ani.options("ani.width"), 
                height = ani.options("ani.height"), res = ani.options("ani.res"))
        }

The error is generated by grepl:

Error in as.character(pattern) : 
  cannot coerce type 'closure' to vector of type 'character'

Possible fix:

if (is.character(ani.options("ani.dev")) && 
    any(grepl(ani.options("ani.dev"), c("png", "bmp", "jpeg", "tiff"))))
yulijia commented 5 years ago

Hi @stla, It is better to provide an example to help us to reproduce the bug. After we reproduce the bug, I think you could send a pull request to this repo based on your solution. I will check it within 24 hours.

stla commented 5 years ago

Hi @yulijia ,

Here is a reproducible example:

library(animation)
saveGIF(
  {
    for(i in 1:2){
      plot(0, 0)
    }
  },
  convert = "convert",
  movie.name = "bug.gif",
  interval = 0.05, ani.width = 500, ani.height = 500,
  ani.dev = function(...) png(bg = "transparent", ...)
)
yulijia commented 5 years ago

Hi @stla , Thank you for providing this helpful example. I made a little change on your code to make sure I could see the dot move on a GIF file.

library(animation)
saveGIF(
  {
    for(i in 1:10){
      plot(i,0)
    }
  },
  convert = "convert",
  movie.name = "bug.gif",
  interval = 0.05, ani.width = 500, ani.height = 500,
  ani.dev = function(...) png(bg = "transparent", ...)
)

Please send a pull request based on your solution. We appreciate your long term support on this package.

Many thanks, Lijia