Skip to content

Add pause/resume methods to Animation baseclass #17689

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

Closed
tacaswell opened this issue Jun 19, 2020 · 13 comments
Closed

Add pause/resume methods to Animation baseclass #17689

tacaswell opened this issue Jun 19, 2020 · 13 comments
Labels
Difficulty: Medium https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! topic: animation
Milestone

Comments

@tacaswell
Copy link
Member

As pointed out in #17685 while you can pause an animation by reaching in and calling methods on the event source, when using Animation with blitting that is not enough, you also have to flip the animated artists back to non-animated. This code (lightly modified from @Luluser question) is a proof-of-concept.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Button


class PlotAnimation:
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        self.x = np.linspace(-10, 10, 1000)
        self.N = 200
        self.interv = 50
        self.n0 = (
            1.0
            / (4 * np.pi * 2e-4 * 0.1) ** 0.5
            * np.exp(-self.x ** 2 / (4 * 2e-4 * 0.1))
        )
        (self.p,) = self.ax.plot(self.x, self.n0)
        self.anim_running = True
        self.Myanimation = animation.FuncAnimation(
            self.fig, self.update, frames=self.N, interval=self.interv, blit=True
        )

    def update(self, i):
        self.n0 += i / 100 % 5
        self.p.set_ydata(self.n0 % 20)
        return (self.p,)

    def animate(self):
        pause_ax = self.fig.add_axes((0.7, 0.025, 0.1, 0.04))
        pause_button = Button(pause_ax, "pause", hovercolor="0.975")
        pause_button.on_clicked(self._pause)
        plt.show()

    def _pause(self, event):
        if self.anim_running:
            self.Myanimation.event_source.stop()
            self.p.set_animated(False)
            self.anim_running = False
            self.fig.canvas.draw_idle()
        else:
            self.p.set_animated(True)
            self.Myanimation.event_source.start()
            self.anim_running = True


animated_plot = PlotAnimation()
animated_plot.animate()

This code should be generalized and used to put a pause and resume methods on Animation.

@tacaswell tacaswell added topic: animation Difficulty: Medium https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! labels Jun 19, 2020
@tacaswell tacaswell added this to the needs sorting milestone Jun 19, 2020
@tacaswell
Copy link
Member Author

For the tags:

  • good first issue because there is very little API design here and only working with a limited slice of the library
  • medium difficulty because you have to read and understand the Animation module. This is probably not a project for someone just learning Python.

@DCtheTall
Copy link
Contributor

DCtheTall commented Jun 22, 2020

Hey, I am interested in trying out working on a solution! I can probably get to it at some point in the coming week when I have some free time.

I have a few years of Python under my belt now and some experience with Python open source projects, so I think I can manage :)

@tacaswell
Copy link
Member Author

Great! We don't have a formal assignment process pre-PR but looking forward to seeing it!

@deep529
Copy link

deep529 commented Jun 23, 2020

Hi,

From the above pasted code, this is the solution I came up with.
This will be implemented in Animation Base Class.

Method to Pause
  • Stop the event using self.event_source.stop()
  • Set the artist to non-animated (Animation class has access to fig object) using
    for ax in self.fig.get_axes():
        for line in ax.get_lines():
            line.set_animated(False)
Method to Resume
  • Set the artist to animated (Animation class has access to fig object) using
    for ax in self.fig.get_axes():
        for line in ax.get_lines():
            line.set_animated(True)
  • Start the event using self.event_source.start()

I tried above solution and it worked as expected.
@tacaswell, Let me know if there is any mistake / improvement possible.

@DCtheTall, I am sorry, I could not found other issues suitable to my knowledge, and would like to continue working on it. (Hope you don't mind.)

@DCtheTall
Copy link
Contributor

DCtheTall commented Jun 24, 2020

@deep529 I am not an owner of this repository, I just volunteered for this issue. I don’t feel it’s my place to decide.

@jklymak
Copy link
Member

jklymak commented Jun 24, 2020

@deep529 Contributions are always welcome. However, if someone else has started working on something, its generally good form to ask before submitting a PR that solves the same problem. So in this case, lets give @DCtheTall a few days to open a PR. If he does, then perhaps you can help by reviewing. Of course, if he doesn't get to it in a few days, feel free to re-ping and we can reconsider. Thanks!

@deep529
Copy link

deep529 commented Jun 24, 2020

@jklymak, totally agree with your point.

But I jumped in because, he mentioned he will start working in the next week when he will get free time.
That's why I thought it is okay for me to try this out.

I did not want to hurt/discourage anyone. Really sorry if I did.

@DCtheTall
Copy link
Contributor

@deep529 thanks for being understanding!

I'm getting to it today. I had replied to the issue on a Sunday night and didn't want to overpromise, which is why I gave the flexible timeframe.

@DCtheTall
Copy link
Contributor

DCtheTall commented Jun 25, 2020

@tacaswell I built the repo on my Debian machine using the instructions here.

I installed matplotlib using python3 -m pip3 install ., and am trying to run tests but getting the following error:

_______________________ ERROR collecting test session _______________________
../../.local/lib/python3.7/site-packages/_pytest/config/__init__.py:495: in _importconftest
    return self._conftestpath2mod[key]
E   KeyError: PosixPath('/usr/local/home/dylancutler/Desktop/matplotlib/lib/matplotlib/tests/conftest.py')

During handling of the above exception, another exception occurred:
../../.local/lib/python3.7/site-packages/py/_path/local.py:704: in pyimport
    __import__(modname)
lib/matplotlib/__init__.py:174: in <module>
    _check_versions()
lib/matplotlib/__init__.py:159: in _check_versions
    from . import ft2font
E   ImportError: cannot import name 'ft2font' from 'matplotlib' (/usr/local/home/dylancutler/Desktop/matplotlib/lib/matplotlib/__init__.py)

Here is my setup.cfg:

[egg_info]

[libs]
system_freetype = False
system_qhull = False

[packages]
tests = True
sample_data = True

Any idea on if I am missing anything? Lmk if you need more info.

EDIT:

It looks like ft2font wasn't built when I ran python -m pip install .. Is there another command I need to build the C++ targets? Thanks in advance.

@DCtheTall
Copy link
Contributor

@tacaswell friendly ping

@jklymak
Copy link
Member

jklymak commented Jun 28, 2020

You may want to look at #17096

@DCtheTall
Copy link
Contributor

@jklymak thanks! Followed the instructions in the PR and was able to run tests.

@dopplershift
Copy link
Contributor

Closed by #17826

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Difficulty: Medium https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues Good first issue Open a pull request against these issues if there are no active ones! topic: animation
Projects
None yet
Development

No branches or pull requests

5 participants