How to create an animation of complicated figures without writing each image to file

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to create an animation of complicated figures without writing each image to file

David Ketcheson
I would like to create an animation from a very complicated plot.  The plot is created by a lot of functions and it's not feasible for me to pass back the handles to all the objects that get added to the plot from all of those functions.  One approach that works is to write each plot to a file and then create an animation by loading the images.  Unfortunately, this doesn't look good, presumably because the images are first rasterized and then the resolution is altered.  

So I'd like to create an animation directly from a set of figures, when all I have are the figures.  I've tried to use get_children() recursively to get all the artists and then use animation.ArtistAnimation(), but so far this only leads to an empty (blank) animation.  Is it possible to do what I'm attempting?

-David


This message and its contents including attachments are intended solely for the original recipient. If you are not the intended recipient or have received this message in error, please notify me immediately and delete this message from your computer system. Any unauthorized use or distribution is prohibited. Please consider the environment before printing this email.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: How to create an animation of complicated figures without writing each image to file

tcaswell
If you have no control over the plotting functions, can not update the artists in place, or just have a sequence of Figure objects, the best approach is probably to so save each frame to png and then use an external program to (eg ffmpeg) stitch them together.  Make sure that you are not using `bbox_inches='tight'`, tight_layour, or contrained layout (so every saved figure is the same size and the axes are in the same place).

If you can re-use the same `Figure` object you can directly use the Writer classes is `matplotlib.animation`, see https://matplotlib.org/api/animation_api.html?highlight=animation#writer-classes .  Those instances are bound to a particular Figure, you _may_ be able to just re-set the figure (but not sure what other state we hold based on the initial figure that might need to be updated as well), at a minimum they should be a good starting point to write your self a "concatenate a list of figures into a movie" writer.

Tom

On Thu, May 31, 2018 at 4:57 AM David Ketcheson <[hidden email]> wrote:
I would like to create an animation from a very complicated plot.  The plot is created by a lot of functions and it's not feasible for me to pass back the handles to all the objects that get added to the plot from all of those functions.  One approach that works is to write each plot to a file and then create an animation by loading the images.  Unfortunately, this doesn't look good, presumably because the images are first rasterized and then the resolution is altered.  

So I'd like to create an animation directly from a set of figures, when all I have are the figures.  I've tried to use get_children() recursively to get all the artists and then use animation.ArtistAnimation(), but so far this only leads to an empty (blank) animation.  Is it possible to do what I'm attempting?

-David


This message and its contents including attachments are intended solely for the original recipient. If you are not the intended recipient or have received this message in error, please notify me immediately and delete this message from your computer system. Any unauthorized use or distribution is prohibited. Please consider the environment before printing this email.
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: How to create an animation of complicated figures without writing each image to file

tcaswell
I do not know of a vector-based movie format, I think you have to rasterize at _some_ point.  Try increasing the dpi or adjusting the encoding parameters /  of ffmpeg (the defaults are not great for plots iirc).

`to_jshtml` writes out movie file and then wraps it in minimal js player.

Tom

On Thu, May 31, 2018 at 9:14 AM David Ketcheson <[hidden email]> wrote:
Thanks for your help!  My replies are interspersed below.

On Thu, May 31, 2018 at 3:38 PM, Thomas Caswell <[hidden email]> wrote:
If you have no control over the plotting functions, can not update the artists in place, or just have a sequence of Figure objects, the best approach is probably to so save each frame to png and then use an external program to (eg ffmpeg) stitch them together.  Make sure that you are not using `bbox_inches='tight'`, tight_layour, or contrained layout (so every saved figure is the same size and the axes are in the same place).

That's what I've been doing, but as I mentioned in my first message, the output isn't what I want -- there are visible artifacts in the resulting movie.  Is there a way to do this without going to a rasterized graphics format? 

If you can re-use the same `Figure` object you can directly use the Writer classes is `matplotlib.animation`, see https://matplotlib.org/api/animation_api.html?highlight=animation#writer-classes .  Those instances are bound to a particular Figure, you _may_ be able to just re-set the figure (but not sure what other state we hold based on the initial figure that might need to be updated as well), at a minimum they should be a good starting point to write your self a "concatenate a list of figures into a movie" writer.

I don't want to write a movie file; my goal is to end up with a JSAnimation-style output (i.e., what you get from anim.to_jshtml()).  I don't see a writer class for that. 
 

On Thu, May 31, 2018 at 4:57 AM David Ketcheson <[hidden email]> wrote:
I would like to create an animation from a very complicated plot.  The plot is created by a lot of functions and it's not feasible for me to pass back the handles to all the objects that get added to the plot from all of those functions.  One approach that works is to write each plot to a file and then create an animation by loading the images.  Unfortunately, this doesn't look good, presumably because the images are first rasterized and then the resolution is altered.  

So I'd like to create an animation directly from a set of figures, when all I have are the figures.  I've tried to use get_children() recursively to get all the artists and then use animation.ArtistAnimation(), but so far this only leads to an empty (blank) animation.  Is it possible to do what I'm attempting?

-David


This message and its contents including attachments are intended solely for the original recipient. If you are not the intended recipient or have received this message in error, please notify me immediately and delete this message from your computer system. Any unauthorized use or distribution is prohibited. Please consider the environment before printing this email.
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: How to create an animation of complicated figures without writing each image to file

Jerzy Karczmarczuk-2
In reply to this post by tcaswell

Le 31/05/2018 à 14:38, Thomas Caswell answers the query of David Ketcheson :

If you have no control over the plotting functions, can not update the artists in place, or just have a sequence of Figure objects, the best approach is probably to so save each frame to png and then use an external program to (eg ffmpeg) stitch them together.

On Thu, May 31, 2018 at 4:57 AM David Ketcheson <[hidden email]> wrote:
I would like to create an animation from a very complicated plot.  The plot is created by a lot of functions and it's not feasible for me to pass back the handles to all the objects that get added to the plot from all of those functions.  One approach that works is to write each plot to a file and then create an animation by loading the images.  Unfortunately, this doesn't look good, presumably because the images are first rasterized and then the resolution is altered.  

So I'd like to create an animation directly from a set of figures, when all I have are the figures.  I've tried to use get_children() recursively to get all the artists and then use animation.ArtistAnimation(), but so far this only leads to an empty (blank) animation.  Is it possible to do what I'm attempting?
But you may save your figure as SVG as well, no?
[Independently of Cairo; on a personal note: I use matplotlib under Anaconda on Windows 10. Cairo is a zombie, it is duly installed by conda, and then refuses to be imported. saying that it doesn't exist Anybody knows what's happening?...]

The SVG produced by Matplotlib is fairly readable, and it can be even edited by hand, and Inkscape accepts it without frowning.

==

If, after several troubles, you decide to pass through the rasterization, perhaps there is no need to save PNGs, just dump your figure on the internal Python canvas and to its region buffer (as string / bytes), and compose using the internal numpy array combination routines.

Regards.

Jerzy Karczmarczuk
/Caen, France/


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users