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

[Bug]: Swallowed error in Jupyter+Matplotlib FuncAnimation. #27822

Open
Carreau opened this issue Feb 25, 2024 · 4 comments
Open

[Bug]: Swallowed error in Jupyter+Matplotlib FuncAnimation. #27822

Carreau opened this issue Feb 25, 2024 · 4 comments

Comments

@Carreau
Copy link
Contributor

Carreau commented Feb 25, 2024

Bug summary

In some case it seem that FuncAnimation in Jupyter + matplotlib widgets + funcanimation just swallow error, leading to hard to debug error as to why animations don't show.

Code for reproduction

Here is a dumb animation where the animate part, raise an error (in the original code this was a typo so a NameError, but for readability, here an assert).

%matplotlib widget

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation 

Nx = 101

x = list(range(10))
def u_func(t):         
    return [x+t//10 for x in range(10)]

fig, ax = plt.subplots()
dt_ms =  50

u0 = u_func(0)
line = ax.plot(x, u0)[0] 



def animate(n):
    """ Fonction principale qui met à jour l'image d'un pas de temps à un autre
    Entrée : 
        n : pas de temps courant
    """
    line.set_ydata(u_func(n))
    assert False, "anything that triggers and error like a typo"
    return line
 
anim = FuncAnimation(fig, animate, interval=dt_ms, frames=50, repeat=True)

Actual outcome

Animation not happening

Expected outcome

Show at least a warnings that the animate function raised

Additional information

I tried to print a trace as to when the animate function get called see

https://gist.github.com/Carreau/e6510855ecab88630f1ea5985a98358c

This is likely multiple problems, matpltolib may want have an explicit warning that animate crash, but ipympl, comm, and ipykernel itself should likely have error messages as well.

Operating system

osx

Matplotlib Version

3.8.3

Matplotlib Backend

module://ipympl.backend_nbagg

Python version

3.11

Jupyter version

4.0.9

Installation

pip

@Carreau Carreau changed the title [Bug]: Swallowed error in Jupyter+Matplotlib Funcanimation. [Bug]: Swallowed error in Jupyter+Matplotlib FuncAnimation. Feb 25, 2024
@dopplershift
Copy link
Contributor

I think you need to trigger the animation to render. You can do this directly with anim.to_jshtml() or anim.to_html5_video(). Should also work by having anim at the end of the cell...BUT:

On my system, mpl.rcParams['animation.html'] is defaulting to 'none', which is causing the _repr_html_() method to return None.

@tacaswell
Copy link
Member

I suspect this is related to the issue with event callbacks where any print calls are not forwarded to the browser.

@Carreau
Copy link
Contributor Author

Carreau commented Feb 27, 2024

think you need to trigger the animation to render. You can do this directly with anim.to_jshtml() or anim.to_html5_video(). Should also work by having anim at the end of the cell...BUT:

On my system, mpl.rcParams['animation.html'] is defaulting to 'none', which is causing the _repr_html_() method to return None.

Yeah, but with the default settings, if you just remove the assert False, the IPython display hook is triggered anyway and the animation works, the animation rendering is triggered, and I don't expect end user to understand those subtleties.

I also confirm that by adding a write to a file and this is triggered.

I suspect this is related to the issue with event callbacks where any print calls are not forwarded to the browser.

Hum that seem more likely, I didn't tracked if the is an try/except in this stack and if it would print anything. I'll see if I can track that down.

@dopplershift
Copy link
Contributor

@Carreau I can reproduce your behavior that it auto-displays properly with the assert removed but we get just a normal repr if the assertion is present. Weird.

None of this makes sense, because the auto-display AFAICT is going through _repr_html_(), which is in its entirety:

    def _repr_html_(self):
        """IPython display hook for rendering."""
        fmt = mpl.rcParams['animation.html']
        if fmt == 'html5':
            return self.to_html5_video()
        elif fmt == 'jshtml':
            return self.to_jshtml()

and I can get the assertion output from both methods called in there.

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

4 participants