Animate two or more figures simultaneously with ma

2019-03-05 06:49发布

问题:

I'm trying to animate two matplotlib figures at the same time. I wrote a script that creates two instances of matplotlib.animation.FuncAnimation, but only one of them animates, the other remains static.

Here's a minimum working example:

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

x=np.linspace(-np.pi,np.pi,100)

# Function for making figures
def makeFigure():
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)

    # Plot a line
    line,=ax.plot(x,np.sin(x))

    return fig,ax,line

# Frame rendering function
def renderFrame(i,line):
    # Apply a phase shift to the line
    line.set_data(x,np.sin(x-i*2*np.pi/100))
    return line,

# Make the figures
figcomps1=makeFigure()
figcomps2=makeFigure()

# Animate the figures
for figcomps in [figcomps1,figcomps2]:
    fig,ax,line=figcomps
    anim=animation.FuncAnimation(fig,renderFrame,fargs=[line])

plt.show()

Is FuncAnimation capable of animating two figures simultaneously? If not, is there another way to simultaneously animate two matplotlib figures?

回答1:

Cause of Issue

You must track each FuncAnimation object separately by holding reference to each individual object.

In your for loop, the FuncAnimation object is being instantiated twice (with name anim), and hence in the namespace, effectively 'overwritten'.

From the Animation Module Docs

...it is critical to keep a reference to the instance object. The animation is advanced by a timer ... which the [Func]Animation object holds the only reference to. If you do not hold a reference to the [Func]Animation object, it (and hence the timers), will be garbage collected which will stop the animation.

Example Solution

Instead, tracking both FuncAnimation objects in, for example a list of FuncAnimation objects, will allow them to both be animated with their own timers

#...

# List of Animation objects for tracking
anim = []

# Animate the figures
for figcomps in [figcomps1,figcomps2]:
    fig,ax,line=figcomps
    anim.append(animation.FuncAnimation(fig,renderFrame,fargs=[line]))

I wish to stress this is only an example, as there are many other methods of tracking multiple objects in a for loop, as explored in this question