Skip to content
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

Artists not in Axes can not be animated with blit=True by FuncAnimation #11135

Open
bersbersbers opened this issue Apr 27, 2018 · 7 comments
Open

Comments

@bersbersbers
Copy link
Contributor

bersbersbers commented Apr 27, 2018

Bug report

Bug summary

Text cannot be animated with blit=True. Code works fine with blit=False.

Code for reproduction

import matplotlib.animation
import matplotlib.pyplot

Animation = matplotlib.animation.FuncAnimation(
    matplotlib.pyplot.figure(),
    lambda x: (matplotlib.pyplot.suptitle(int(x)),),
    frames=1,
    blit=True)
matplotlib.pyplot.show(block=True)

Actual outcome
This error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python36\lib\tkinter\__init__.py", line 1702, in __call__
    return self.func(*args)
  File "C:\Program Files\Python36\lib\tkinter\__init__.py", line 746, in callit
    func(*args)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\backends\_backend_tk.py", line 88, in _on_timer
    TimerBase._on_timer(self)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\backend_bases.py", line 1373, in _on_timer
    ret = func(*args, **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\animation.py", line 1481, in _step
    still_going = Animation._step(self, *args)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\animation.py", line 1217, in _step
    self._draw_next_frame(framedata, self._blit)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\animation.py", line 1237, in _draw_next_frame
    self._post_draw(framedata, blit)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\animation.py", line 1260, in _post_draw
    self._blit_draw(self._drawn_artists, self._blit_cache)
  File "C:\Program Files\Python36\lib\site-packages\matplotlib\animation.py", line 1274, in _blit_draw
    bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
AttributeError: 'NoneType' object has no attribute 'bbox'

Expected outcome

A plot with suptitle 0.

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: matplotlib==2.2.2
  • Matplotlib backend: TkAgg
  • Python version: 3.6.5
  • Jupyter version (if applicable): none
  • Other libraries:

Python from https://www.python.org/
Matplotlib using pip

@ImportanceOfBeingErnest
Copy link
Member

The error above does not actually show any error. But probably it's something like "Text has no attribute axes" or "None has no attribute bbox" or so?

Blitting blits the axes, not the complete figure. plt.suptitle is not part of any axes.
But even an axes title, which is part of an axes, would not be visibly updated, simply because it's shown outside of the axes bounding box.

The least that can be done here is for sure to add a sentence in the docs that figure artists are not supported by blitting. Apart, I'm unsure if blitting should be extended to use the figure instead of the axes. One could probably use the figure bbox instead of the axes to save and restore for blitting; I'm not sure in how far this makes things less efficient (of course a larger image takes longer to restore).

@bersbersbers
Copy link
Contributor Author

@ImportanceOfBeingErnest yes, I had only copied part of the error message by mistake (microsoft/vscode#18788). I have updated the original post. The error message is indeed AttributeError: 'NoneType' object has no attribute 'bbox'.

@quantshah
Copy link

Hi, thanks for raising this. I was also trying to blit some text but it didn't work. Any alternative solutions? I am not thinking of making images separately and combining them as a gif.

@ImportanceOfBeingErnest
Copy link
Member

@sahmed95 The issue here is that text outside of the axes is not updated in the blitting process. You may easily use text within the axes instead. You may also manually blit the text if needed, or write your custom animation to blit the complete figure instead of the axes. If however the aim is to create a gif, blitting is not useful at all (a saved image will always draw each frame in completeness), hence you can simply set blit=False.
For help with your issue, you may inquire at Stackoverflow or the mailing list but make sure to detail the use case with a minimal and runnable example code and your attempts to solve the issue.

@github-actions
Copy link

github-actions bot commented Jun 5, 2023

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jun 5, 2023
@ksunden
Copy link
Member

ksunden commented Jun 5, 2023

This still does raise, though at a (very) slightly different line of code:

Traceback (most recent call last):
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/backend_bases.py", line 1228, in _on_timer
    ret = func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/animation.py", line 1414, in _step
    still_going = super()._step(*args)
                  ^^^^^^^^^^^^^^^^^^^^
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/animation.py", line 1107, in _step
    self._draw_next_frame(framedata, self._blit)
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/animation.py", line 1127, in _draw_next_frame
    self._post_draw(framedata, blit)
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/animation.py", line 1150, in _post_draw
    self._blit_draw(self._drawn_artists)
  File "/home/kyle/src/scipy/matplotlib/lib/matplotlib/animation.py", line 1165, in _blit_draw
    cur_view = ax._get_view()
               ^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_get_view'

Fundamentally, it comes down to the _blit_draw acting on Artist.axes for the blitting, but text placed in a figure, has no self.axes (i.e. self.axes=None)

Even if the initial fix of averting the error were implemented, it is not clear to me that the expected behavior would happen, as there is no "blit over the whole figure" code in _blit_draw, and I suspect that would have other implications from overlapping blit boundaries that would lead to unexpected behavior.

Perhaps the course of action here is to simply raise a more informative error if fig-based text cannot be blitted properly, or to special case the bbox for text (though that in and of itself gets complicated because the bbox changes).

@github-actions github-actions bot removed the status: inactive Marked by the “Stale” Github Action label Jun 7, 2023
@tacaswell tacaswell changed the title Text cannot be animated with blit=True Artists not in Axes can not be animated with blit=True by FuncAnimation Aug 4, 2023
@GSh47
Copy link

GSh47 commented Apr 24, 2024

has there been any fix for the issue ? I have a similar error myself with the _blit_draw's cur_view = ax._get_view()

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

No branches or pull requests

6 participants