当 blit=true matplotlib FuncAnimation 时,'Line2D' 对象不是可迭代错误

lod*_*ous 1 python animation matplotlib fractals jupyter-notebook

我正在尝试使用 FuncAnimation 在 matplotlib 中为一些分形设置动画。当我将 blit 设置为 False 时,我没有收到任何错误:代码运行良好并为我生成了一个不错的动画。但是,当我将 blit 设置为 True 时,它​​给了我TypeError: 'Line2D' object is not iterable. 有谁知道为什么会发生这种情况以及我该如何解决?

我想利用 blitting 的优势,因为我计划为一大群分形制作动画,并且只取其中的一小部分(64 个不同的分形)已经花费了大量的计算时间。我有一种快速的方法来生成一个矩阵,其中列包含不同的分形,所以我知道计算时间是花在尝试为一堆图设置动画而不是 blitting 上的。

在我的示例中,我只是为生成分形的迭代设置动画。这是说明我得到的错误的一种简短而快速的方法,而不是我实际尝试动画的方式,否则我不会关心 blitting。

如果您安装了 ffmpeg,这是一个应该在 jupyter notebook 中运行的最小示例:

import numpy as np
import scipy as sp
import scipy.linalg as la
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import animation, rc
from IPython.display import HTML
%matplotlib inline
plt.rcParams['figure.figsize'] = [8,8]
plt.rcParams['animation.ffmpeg_path'] = "C:\\Program Files\\ffmpeg\\bin\\ffmpeg.exe" #<- CHANGE TO YOUR PATH TO FFMPEG or delete this line if the notebook knows where to find ffmpeg.
class IFS:
    """Represent an iterated function system used to generate a fractal."""
    def __init__(self,start,f1,f2,reversef2=False):
        self.points = start
        self.f1 = f1
        self.f2 = f2
        self.reversef2 = reversef2

    def iterate(self,iterations=1):
        """Perform iterations using the functions"""
        for i in range(0,iterations):
            if self.reversef2: #This is needed for the dragon curve
                self.points = np.append(self.f1(self.points),self.f2(self.points)[::-1])
            else: #However, you do not want to append in reverse when constructing the levyC curve
                self.points = np.append(self.f1(self.points),self.f2(self.points))

    def get_points(self):
        return self.points

def dragon_ifs():
    """Return a dragon fractal generating IFS"""
    def f1(z):
        return (0.5+0.5j)*z
    def f2(z):
        return 1 - (0.5-0.5j)*z
    return IFS(np.array([0,1]),f1,f2,reversef2=True)

#Animation
class UpdateFractal:
    """A class for animating an IFS by slowly iterating it"""
    def __init__(self,ax,ifs):
        self.ifs = ifs
        self.line, = ax.plot([], [], 'k-',lw=2)
        self.ax = ax
        #set parameters
        self.ax.axis([-1,2,-1,2])
    def get_plot_points(self):
        """Get plottable X and Y values from the IFS points"""
        points = self.ifs.get_points()
        X = points.real
        Y = points.imag
        return X,Y
    def init(self):
        X,Y = self.get_plot_points()
        self.line.set_data(X,Y)
        return self.line
    def __call__(self,i):
        self.ifs.iterate()
        X,Y = self.get_plot_points()
        self.line.set_data(X,Y)
        return self.line

fig, ax = plt.subplots()
dragon = dragon_ifs()
uf = UpdateFractal(ax,dragon)
anim = FuncAnimation(fig, uf, frames=np.arange(15), init_func=uf.init,
                     interval=200, blit=True)
#Show animation
HTML(anim.to_html5_video())
Run Code Online (Sandbox Code Playgroud)

旁注:我也看到了这个未回答的问题:FuncAnimation not iterable,我认为他们可能面临类似的问题。我注意到他们将 blit 设置为 True,如果我有足够的声誉,我会发表评论并询问他们是否将 blit 设置为 False “修复”了他们的问题。

Imp*_*est 10

正如错误所暗示的那样,动画函数的返回需要是可迭代的。

更换线return self.line通过

return self.line, 
Run Code Online (Sandbox Code Playgroud)

注意逗号