I have a DensityPlot
which is evaluated for a long time. I wish to use it with animation, but it is absolutely inapropriate.
Is it possible to render animation first and then run it smoothly?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI have a DensityPlot
which is evaluated for a long time. I wish to use it with animation, but it is absolutely inapropriate.
Is it possible to render animation first and then run it smoothly?
Here is an example of how to create an animation from DensitPlot results. I have chosen a simple Gaussian function to plot, but its center depends on a parameter t
. Now I create a table of plots for many different values of t
, and then I take several different steps to create various kinds of movies from it. The parameter t
and its step size is going to be the main variable that you have to decide on depending on your application, in order to make a smooth animation.
Note on speed
To save time, you should execute the following commands in separate cells, and only choose the export or display method that you need. Otherwise the evaluation will probably stretch your patience.
exampleFrames =
Table[
DensityPlot[
Evaluate[
Exp[-((x - Cos[t])^2 + (y - Sin[t])^2)/.025]
],
{x, -1.5, 1.5}, {y, -1.5, 1.5},
ColorFunction -> GrayLevel,
PlotRange -> All,
PlotPoints -> 30,
Frame -> None,
PlotRangePadding -> None
],
{t, Pi/50, 2 Pi, Pi/50}
];
rasterizedFrames = Map[Image, exampleFrames];
Export["movie.mov", exampleFrames];
Export["movie.avi", exampleFrames];
ListAnimate[rasterizedFrames]
What I did above is to first rasterize the individual frames before making the ListAnimate
.
Update: thanks to Alexey Popkov for reminding me that Image
can be used instead of Rasterize
to perform the rasterization more efficiently.
Working with rasterizedFrames
speeds up the ListAnimate
process. This is especially noticeable if your movie has 3D
graphics as frames. Rasterization allows you in principle to customize the quality of the video frames. For the export as .mov
and .avi
, though, it seems to be faster to not use the pre-rasterized frames and instead start from the original exampleFrames
.
If you want the movie in Flash format, do this:
Export["movie.swf", rasterizedFrames];
In the Flash file, rasterization leads to a smaller file size but the export takes longer for this format.
Edit
Thanks to @halirutan for pointing out that Rasterize
gets much faster when replacing the above instruction by:
rasterizedFrames = Map[Rasterize[#,"Image"]&, exampleFrames];
Update In Mathematica version 9, though, I see no speed difference with our without the "Image"
argument.
ListAnimate
is the easiest way to create animations in Mathematica, but it can sometimes by so horribly slow that the notebook becomes unresponsive. This may happen if you have many frames with complicated plots.
That's why I also included some Export
commands that generate movies in standard formats that can be read by other applications (media players). The file movie.mov
should be a Quicktime movie, and movie.swf
is a Flash animation.
Finally, depending on your operating system, it may in fact be best to create the movie in an external application. In that case, you can do the following:
Export["movie001.png", exampleFrames, "VideoFrames"];
This will create all the frames as individual files numbered movie001.png, movie002.png, etc. These can subsequently assembled in a movie editor.
If you want to go that route, that's a different topic that I have discussed some more on the following page: Mathematica image sequence export
"VideoFrames"
Export
option. Didn't know about that one!
$\endgroup$
– Thies Heidecke
Jan 12 '13 at 0:07
Yes, you can create a table of the plots at appropriate time intervals and then use ListAnimate[]
on the table.
Although the best answer is already accepted, I think something really important was not pointed out here. It's the existence of an Image
type which was introduced in Mathematica 7. Everything I have seen so far points to that this type adds a significant improvement to rendering speed.
Therefore, when someone wants to convert a list of graphics into a rasterized format for fast rendering, the usage of Rasterize
is not sufficient, since this does not create an Image
, but a Graphics[Raster[...]]
expression. The call to Rasterize
should always be used with "Image" as second argument.
Please try it yourself with a list of 50 DensityPlot
s similar to the one @Jens used in his answer
exampleFrames =
Table[DensityPlot[Sin[t x] Sin[t y], {x, -4, 4}, {y, -3, 3},
ColorFunction -> "SunsetColors", PlotRange -> All,
PlotPoints -> 30, Frame -> None, PlotRangePadding -> None], {t, 0, 2, 2/49.}];
And now compare the speed of calls to ListAnimate
where the plots are converted to a raster format. You should use a stopwatch for this, since neither Timing
nor AbsoluteTiming
seems to be able to get the time correctly. First, with normal Rasterize
ListAnimate[Rasterize[#] & /@ exampleFrames]
This takes about 50 seconds here on my MacBook. Now, use "Image" to tell Rasterize
, that it should create Images
ListAnimate[Rasterize[#, "Image"] & /@ exampleFrames]
This takes only 5 seconds on the same machine. Even the rendering seems to run more fluent from the beginning, where with the first version it seems to take some loops before the ListAnimate
runs smoothly.
Note that even the export of a list of Images
is faster than the export of Graphics[Raster[...]]
.
Rasterize[#,"Image"]&
and Image
give identical results: Image@# === Rasterize[#, "Image"] &@# & /@ exampleFrames
. It is documented behavior.
$\endgroup$
– Alexey Popkov
Jan 11 '13 at 8:53
"Image"
was much slower even if the result was the same! I think it's fixed in version 9.
$\endgroup$
– Jens
Jan 11 '13 at 16:03
Image
is still superior as compared to Raster
at least in memory cosumption: ByteCount /@ {Rasterize@#, Image@#} &@exampleFrames[[10]]
. Note that in both cases ImageType
is "Byte"
.
$\endgroup$
– Alexey Popkov
Jan 11 '13 at 18:39
Image[]
s before feeding them to Export[]
; it certainly went a lot quicker than running ListAnimate[]
through those frames.
$\endgroup$
– J. M.'s ennui♦
Feb 7 '12 at 7:39