Using matplotlib.animation inside a function in Canopy [duplicate]
Asked Answered
I

1

2

The following script produces a simple animation of a traveling sine wave when executed using the %run statement in Canopy 1.4.1:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

def animator():
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
    line, = ax.plot([], [], lw=2)

    def init():
        line.set_data([], [])
        return line,

    def animate(i):
        x = np.linspace(0, 2, 1000)
        y = np.sin(2 * np.pi * (x - 0.01 * i))
        line.set_data(x, y)
        return line,

    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                frames=200, interval=20, blit=True)

    plt.show()

animator()

However, if I remove the last line, run the script with %run and call animator() from the interpreter, only the first frame is drawn on the screen. Why is this? How can I get a function call to produce an animation within Canopy?

Oddly, this problem does not occur in either IDLE or IPython (PyLab), where calling animator() from the interpreter works fine. What is more, the issue is limited to the interactive display: if I add a few more lines to animator to save the animation in mp4 format, the mp4 file is saved correctly even from Canopy.

The code above is based on a tutorial by Jake Vanderplas.

Irmgardirmina answered 27/8, 2014 at 22:8 Comment(0)
I
2

I have figured out an answer to the second part of my question: as suggested in this answer, I must have the function return anim. But I remain somewhat confused as to why Canopy and the other interpreters behave differently here. (Why do IDLE and PyLab work?) Any insight would be appreciated!

Irmgardirmina answered 27/8, 2014 at 22:8 Comment(7)
It's possible that Canopy is using different matplotlib settings than IDLE or PyLab (such as interactive mode).Betweenwhiles
As the answer you reference implies, the behavior of your problem code is undefined because it relies on an object which has been deleted and is available for garbage collection. By default, Canopy uses pylab with the Qt graphics backend. The standard pylab shortcut, and pylab from a command prompt, and IDLE, all use the older Wx backend. It is not surprising that different graphic backends behave differently when the behavior is undefined. Perhaps Qt, being more modern and performant than Wx, does garbage collection more energetically.Kristoferkristoffer
BTW, if you use the Canopy Preferences (Python tab) to change the backend from Qt to Wx, you'll find that Canopy also displays the graph like the other two environments do. It's about the backend, not about the environment. BTW2: Incorrect code which happens to produce the result that you wanted is hardly "working", and the environment where you are running the code is hardly "working" or "not working" depending on whether the result is what you expected.Kristoferkristoffer
It depends on what garbage collection is called.Kaliope
@JonathanMarch Sorry, I suspect I just prevented you from posting an answer.Kaliope
I would abuse the system and put those comments as an answer to the question marked as a duplicate (prefaced by this may work in some cases but,....).Kaliope
@tcaswell, yes, unlucky timing, not to worry. Added link here as comment to your answer there. meh.Kristoferkristoffer

© 2022 - 2024 — McMap. All rights reserved.