Thanks to visit codestin.com
Credit goes to github.com

Skip to content

DOC: Use Sphinx-gallery animation capture #17477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 22, 2020
Merged

Conversation

larsoner
Copy link
Contributor

@larsoner larsoner commented May 21, 2020

PR Summary

  1. Use the Matplotlib animation capture built into Sphinx-gallery 0.7.0 to capture animations.
  2. Update to latest syntax for mini-gallery inclusion
  3. Add image compression (optipng)
  4. EDIT: Add a make show target in doc/Makefile to make it easier to pop open the built docs
  5. EDIT: Add SciPy to the doc build requirements
  6. EDIT: Rename a double_pendulum_sgskip to actually build

It does move some animations into the slowest category (local build times with this PR):

    - ../examples/style_sheets/style_sheets_reference.py:                          15.52 sec   0.0 MB
    - ../examples/animation/animate_decay.py:                                      12.85 sec   0.0 MB
    - ../tutorials/intermediate/constrainedlayout_guide.py:                        12.30 sec   0.0 MB
    - ../examples/animation/animated_histogram.py:                                 11.79 sec   0.0 MB
    - ../examples/animation/strip_chart.py:                                        11.09 sec   0.0 MB
    - ../tutorials/colors/colormaps.py:                                            10.36 sec   0.0 MB
    - ../examples/animation/animation_demo.py:                                      8.99 sec   0.0 MB
    - ../examples/animation/unchained.py:                                           7.68 sec   0.0 MB
    - ../examples/animation/bayes_update.py:                                        7.60 sec   0.0 MB
    - ../examples/lines_bars_and_markers/markevery_demo.py:                         7.00 sec   0.0 MB
    - ../examples/animation/simple_anim.py:                                         6.33 sec   0.0 MB
    - ../tutorials/intermediate/gridspec.py:                                        6.09 sec   0.0 MB
    - ../examples/subplots_axes_and_figures/subplots_demo.py:                       5.40 sec   0.0 MB
    - ../tutorials/introductory/images.py:                                          5.39 sec   0.0 MB
    - ../tutorials/intermediate/tight_layout_guide.py:                              4.95 sec   0.0 MB
    - ../examples/animation/rain.py:                                                4.58 sec   0.0 MB
    - ../examples/animation/random_walk.py:                                         4.57 sec   0.0 MB

It might be possible to optimize these examples to be faster (I haven't looked/tried). Or maybe it's acceptable already...

PR Checklist

  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant

Looks like this on my machine

Peek 2020-05-21 13-47

Peek 2020-05-21 13-48

Let's see if CircleCI agrees!

Happy to iterate here if people agree it's worth having, let someone else take over if they want, or scrap it if it's not worth adding.

@larsoner
Copy link
Contributor Author

... and adds a make show target in doc/Makefile to make it easier to pop open the built docs

@tacaswell tacaswell added this to the v3.3.0 milestone May 21, 2020
@story645
Copy link
Member

I'm very very psyched, but why are some of the examples not showing? Is there something that can be done on matplotlib's side to get that working?

@larsoner
Copy link
Contributor Author

During build I see:

Animation size has reached 21248815 bytes, exceeding the limit of 20971520.0. If you're sure you want a larger animation embedded, set the animation.embed_limit rc parameter to a larger value (in MB). This and further frames will be dropped.

I'll bump this up in doc/matplotlibrc, it's very close to the limit. Here is how it looks thus far:

https://37238-1385122-gh.circle-artifacts.com/0/doc/build/html/gallery/index.html#animation

I'm very very psyched, but why are some of the examples not showing?

  • It currently only processes the FuncAnimation examples, because I didn't think to implement ArtistAnimation support at the Sphinx-gallery end (didn't actually know about it and didn't investigate all the options).
  • At least a couple of the examples (e.g., "pyplot animation") just loop directly rather than using a *Animation object.
  • one of the examples uses interval=2 which goes super fast, which might break the GIF thumbnailing (it animates in the example)

I'll take a quick pass at making the ones that do use FuncAnimation build a bit more nicely.

@tacaswell
Copy link
Member

How are you identifying the animation object to capture?

We want to leave at least some of the "plt.pause in a loop" exmaple as is. For simple things it is enough and we don't want to suppress it.

@larsoner
Copy link
Contributor Author

How are you identifying the animation object to capture?

Global variable inspection isintance(var, FuncAnimation) currently. So probably just needs to expand to include ArtistAnimation via tuple or a super class if there is one

We want to leave at least some of the "plt.pause in a loop" exmaple as is. For simple things it is enough and we don't want to suppress it.

Indeed, not planning to change that one. But the double_pendulum seems like it should be okay to run so I'm going to try removing its sgskip...

@tacaswell
Copy link
Member

I would go with matplotlib.animation.Animation as the base class.

@larsoner
Copy link
Contributor Author

Done in sphinx-gallery/sphinx-gallery#693 , will have to wait for 0.7.1 to land before it takes effect, though. In the meantime I've added scipy to the doc build requirements so that the pendulum example can run (and be removed from sgskip) -- scipy is easily pip-installable nowadays so it doesn't seem too onerous. If you disagree I can restore the sgskip status, but it does look cool -- locally with the SG PR branch I now see:

Peek 2020-05-21 15-09

The CircleCI build should produce the same thing, except that the dynamic_imag.py example won't animate (though I did make it so that it should produce a still image rather than a blank canvas now).

@larsoner
Copy link
Contributor Author

CircleCI output can be viewed here.

Now the animation timings are:

    - ../examples/animation/strip_chart.py:                                        27.75 sec   0.0 MB
    - ../examples/animation/double_pendulum.py:                                    27.36 sec   0.0 MB
    - ../examples/animation/animate_decay.py:                                      26.73 sec   0.0 MB
    - ../examples/animation/random_walk.py:                                        18.80 sec   0.0 MB
    - ../examples/animation/unchained.py:                                          15.93 sec   0.0 MB
    - ../examples/animation/bayes_update.py:                                       13.91 sec   0.0 MB
    - ../examples/animation/simple_anim.py:                                        13.38 sec   0.0 MB
    - ../examples/animation/animated_histogram.py:                                 12.40 sec   0.0 MB
    - ../examples/animation/animation_demo.py:                                      9.19 sec   0.0 MB
    - ../examples/animation/rain.py:                                                8.14 sec   0.0 MB

And the non-animation ones in roughly the same range for reference:

    - ../examples/style_sheets/style_sheets_reference.py:                          27.31 sec   0.0 MB
    - ../tutorials/intermediate/constrainedlayout_guide.py:                        23.00 sec   0.0 MB
    - ../tutorials/colors/colormaps.py:                                            19.41 sec   0.0 MB
    - ../examples/lines_bars_and_markers/markevery_demo.py:                        13.22 sec   0.0 MB
    - ../tutorials/intermediate/gridspec.py:                                       12.41 sec   0.0 MB
    - ../examples/subplots_axes_and_figures/subplots_demo.py:                       9.88 sec   0.0 MB
    - ../tutorials/intermediate/tight_layout_guide.py:                              8.93 sec   0.0 MB
    - ../tutorials/introductory/images.py:                                          8.87 sec   0.0 MB
    - ../examples/showcase/mandelbrot.py:                                           8.21 sec   0.0 MB

So there is something like a 2-3 minute time penalty from rendering these animations now. If this is too much time, I can work on trimming them. Ready for merge from my end otherwise!

@story645 story645 linked an issue May 21, 2020 that may be closed by this pull request
@@ -49,14 +49,14 @@ def emitter(p=0.03):
yield np.random.rand(1)

# Fixing random state for reproducibility
np.random.seed(19680801)
np.random.seed(1968080)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
np.random.seed(1968080)
np.random.seed(19680801)

One of the sentimental things we do is seed the random numbers to John Hunter's birthday. Would rather not change this unless there is a compelling reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intentional -- the original seed did not yield many spikes for the given probability (and increasing the probability further made too many spikes) over the first few seconds of the animation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about I write it as 19680801 // 10? Same effect but preserves the birthday in there?

Copy link
Contributor Author

@larsoner larsoner May 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Or I could test if 0 or 41 EDIT: 42 or 1337 or some other "principled" choice of seed gives something that plays well in the animation)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

19680801 // 10 <- if that looks good 👍

Could also "prime" the stream a bit by generating and discarding a bunch of numbers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed the // 10 let's see if CircleCI produces something reasonable -- it should!

@tacaswell
Copy link
Member

I am 👍 on adding scipy as a docs build dependancy (as I thought it already was), but we should note that change as well (attn @timhoffm @QuLogic )

@larsoner
Copy link
Contributor Author

git grep scipy in examples suggests that examples/images_contours_and_fields/irregulardatagrid.py has a code snippet that could be simplified using / refers to scipy.interpolate as a shortcut. Can push here if it's helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Animation Examples
4 participants