首页 文章

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

提问于
浏览
0

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

我想利用blitting,因为我计划为一大片分形动画制作动画,只需要一小部分(64种不同的分形)已经占用了明显的计算时间 . 我有一个快速的方法来生成一个矩阵,其中包含不同分形的列,所以我知道计算时间花在尝试动画一堆没有blitting的图上 .

在我的例子中,我只是动画生成分形的迭代 . 这是一个简短而快速的方式来说明我得到的错误,而不是我实际上试图制作动画,因为否则我不会关心blitting .

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

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())

旁注:我看到这个问题也是未解决的问题:FuncAnimation not iterable我认为他们可能面临类似的问题 . 我注意到他们将blit设置为True,如果我有足够的声望,我会评论并询问他们是否设置了blit to False "fixes"他们的问题 .

1 回答

  • 2

    如错误所示,动画函数的返回需要是可迭代的 .

    将行 return self.line 替换为

    return self.line,
    

    note the comma

相关问题