The previous method I posted used ListPlot
to generate the frames for the animation, but this is a very slow way to do it if you want to animate thousands of frames. A much quicker way is to just use graphics primitives like in the original post.
Here is a very fast function that will animate an unknown number of particles. I found that using ListAnimate
slowed down the execution considerably over Animate
, so that is what is used here. Keep in mind, it's usually better to use ListAnimate
as it compiles the entire animation before showing it to you so it can handle errors better. When toying around here, I had initially neglected to have Animate
only vary the parameter n
by integer values, and this made my notebook nearly unresponsive. It's also possible that ListAnimate
and Animate
use different amounts of memory, but I'm not certain of that.
animation[datalist_, plotopts : OptionsPattern[]] :=
Module[{point, data2, nparticles, colorlist, imglist, opts, prange},
(*A simple function to create the graphics primitives*)
point[color_, coords_] := {PointSize[0.025], color, Point[coords]};
(*Partition the data into the right dimensionality*)
data2 = Partition[#, 2] & /@ datalist;
(*Generate a list of distinct colors for every particle*)
nparticles = Length@data2[[1]];
colorlist = Hue /@ Range[0, 1., 1./nparticles][[2 ;;]];
(*Generate the list of images*)
prange = {#, #} &@Through[{Max, Min}[datalist]];
imglist =
Graphics[point @@@ Transpose[{colorlist, #}],
Evaluate[FilterRules[{plotopts}, Options[Graphics]]],
PlotRange -> prange] & /@ data2;
(*Animate the list of images -
the slower `ListAnimate` is commented out in favor of the more primitive `Animate` *)
(*ListAnimate[imglist]*)
Animate[imglist[[n]], {n, 1, Length@imglist, 1},
AnimationRate -> 30, AnimationRunning -> True]
]
This can work on OP's data set in about 0.06 seconds on my machine (versus about 50 seconds for the ListPlot
solution)
opdata = Import["http://pastebin.com/raw.php?i=6sccqHr8", "Table"];
animation[opdata, BaseStyle -> 20, FrameLabel -> {"x", "y"},
Axes -> False, Frame -> True] // AbsoluteTiming
You can even apply it to a list with 60 particles, and still less than half a second
randomdata =
Transpose[
Table[Accumulate[
Prepend[RandomReal[{-0.2, 0.2}, {3000}],
RandomReal[{-10, 10}]]], {2*60}]];
animation[randomdata, BaseStyle -> 20, FrameLabel -> {"x", "y"},
Axes -> False, Frame -> True] // AbsoluteTiming
Of course, if you want to export the animation for viewing outside the notebook, I would definitely recommend exporting the individual frames as image files and converting them using another program. Mathematica is not great at outputting movie files in my experience.
Partition
to break the list onto coordinate pairs, and exploit the fact thatPoint
can contain more than a single point, i.e.Point[{{x1,y1},{x2,y2}}]
is valid. Also, considerListAnimate
instead ofAnimate
. $\endgroup$