Open ctmccull opened 2 years ago
You have reorganized some of the content and placed things inside the loop that were outside.
As a result, every time through they loop they are being recreated. For example, your data consists of a bunch of random steps that move the location of the dot by small increments. If you recreate that data vector each time through the loop there will be no continuity - the dot will bounce around the graph without following any path.
You also added the parameter par( ask=T ) to the loop. This means to ask the user for the next plot in a series of plots. It allows you to click through the graphs in real-time like it is a slow animation. They might break the animation feature, though, because it will be waiting for you to proceed to the next graph manually.
The par() commands are setting global plot parameters, so they only need to be set once.
Does that make sense?
Make sure to split out the data creation from the plot creation steps:
# create a directory for your images
dir.create("gifs")
setwd("gifs")
library( animation )
x <- cumsum( rnorm(100) )
y <- cumsum( rnorm(100) )
max.x <- max(x)
min.x <- min(x)
max.y <- max(y)
min.y <- min(y)
par( ask=T )
par( mar=c(2,2,3,1) )
saveGIF({
for( i in 5:100 )
{
plot( x[i], y[i], pch=19, cex=2, xlim=c(min.x,max.x), ylim=c(min.y,max.y) )
}
},
movie.name = "movie_name.gif", # name of your gif
interval = 0.3, # controls the animation speed
ani.width = 800, # size of the gif in pixels
ani.height = 800 ) # size of the git in pixels
It might be that the arguments in the package changed since the example was created. Please report back on if this works.
That definitely makes sense! I took out the data creation and separated it from the plot creation, so that's all good now. However, the same error is still coming up regarding the 'fps' argument.
I think I got it! I finally googled what the 'fps' argument even was and it stands for "frames per second", which you probably knew. Anyway, that got me thinking that I needed to change "interval =" to a factor of 100. I tried interval = 0.10 and it worked!
So, here the function: https://github.com/yihui/animation/blob/master/R/im.convert.R
magick.convert = function(files, output, interval = 1, loop = 0, dispose = NULL){
if (!length(dispose)) dispose = "background"
dispose = tolower(dispose)
img = magick::image_read(files, strip = TRUE)
anim = magick::image_animate(img, loop = loop, fps = 100 / as.integer(interval * 100), dispose = dispose)
magick::image_write(anim, path = output)
}
And the magick::image_animate() documentation states that it requires factors of 100.
If you look up the function there: https://github.com/ropensci/magick/blob/master/R/animation.R
You find:
if(100 %% fps)
stop("argument 'fps' must be a factor of 100")
Which is where the error is coming from. The modulus operator %% returns the remainder from division:
100 %% 10
[1] 0
100 %% 100
[1] 0
> 100 %% 30
[1] 10
I just now learned that you can use 0 or 1 as values in if() statements. 0=FALSE, 1=TRUE.
if( 0 ){ print("x") }
if( 1 ){ print("x") }
[1] "x"
So there you go. Interval would need to produce zero here:
interval <- 0.25
fps <- 100 / ( interval * 100 )
100 %% fps
[1] 0
How's that for a wormhole?
When you see the term "dependency" in documentation it means this - when the performance of your code depends upon code in another package, and thus changes to that package can impact your code!
Wow! That's both fascinating and anxiety-producing. I'm glad to know about dependency now, so I can keep my eye out for scenarios like this if a package were to ever change. Thank you for your help!
Yep, you caught the important part and were able to problem-solve:
argument 'fps' must be a factor of 100
But you can see how the animate package is a wrapper for image magick, which is called through the magick package.
The error occurs in the magick package, then is sent back through the function you called in the animate package.
The interesting thing to note is the code it returns is a combination of code from both functions:
Error in magick::image_animate(img, loop = loop, fps = 100/as.integer(interval * : argument
But it tells you where the error occurs: magick::image_animate()
This is called error tracing and is really important for debugging because you know which chunk of code is actually triggering the error then. Sometimes you have no idea and need to trace it yourself with special debugging functions.
Kind of a miracle that any of it works as well as it does!
Error in magick::image_animate(img, loop = loop, fps = 100/as.integer(interval * : argument 'fps' must be a factor of 100
I keep receiving this error when trying to animate the random walk from the lecture. Is there a way to edit the fps argument? Am I just completely missing something?