【问题标题】:Extra Frame in matplotlib.animation.FuncAnimatematplotlib.animation.FuncAnimation 中的额外帧
【发布时间】:2020-07-01 15:00:28
【问题描述】:

我正在使用 matplotlib 动画探索实时图表。目前,我只是将一个随机整数添加到一个数组中,并根据新数字更新我的绘图。问题是我似乎在情节中获得了额外的价值。

我有以下代码:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random

fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)

xs = []
ys = []

def animate(i, xs, ys):
    
    x = i + 1
    y = random.randint(1, 50)
    
    print '{}: {}, {}'.format(i, x, y)
    
    xs.append(x)
    ys.append(y)
            
    ax1.clear()
    ax1.plot(xs, ys)
        
ani = animation.FuncAnimation(fig,
                              animate,
                              frames = 10,
                              fargs = (xs, ys),
                              repeat = False)
plt.show()

我只想绘制 10 个值,所以我在 FuncAnimate 调用中设置了 frames = 10。但是,打印语句输出的是第 11 个值:

所以很明显正在生成 11 个帧,而不是 10 个。查看FuncAnimate 的文档,我看不出发生这种情况的原因。

谁能告诉我我错过了什么?

谢谢!

【问题讨论】:

    标签: python matplotlib animation random matplotlib-animation


    【解决方案1】:

    也许这不是最优雅的解决方法,但您可以使用标志作为解决方法,以避免在第一个循环中运行动画:

    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    import random
    
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    
    xs = []
    ys = []
    
    flag = 0
    def animate(i, xs, ys):
    
        global flag
    
        if i == 0 and flag == 0:
            flag = 1
            return
    
        if flag == 1:
            x = i + 1
            y = random.randint(1, 50)
    
            print '{}: {}, {}'.format(i, x, y)
    
            xs.append(x)
            ys.append(y)
    
            ax1.clear()
            ax1.plot(xs, ys)
    
    
    ani = animation.FuncAnimation(fig,
                                  animate,
                                  frames = 10,
                                  fargs = (xs, ys),
                                  repeat = False)
    plt.show()
    

    输出:

    0: 1, 37
    1: 2, 2
    2: 3, 46
    3: 4, 39
    4: 5, 30
    5: 6, 47
    6: 7, 16
    7: 8, 3
    8: 9, 3
    9: 10, 49
    

    剧情:


    编辑
    我做了一些研究。 这种行为是因为您(和我)没有指定FuncAnimationinit_func 参数。正如您可以从documentation 中看到的那样:

    init_func : callable, optional 用于绘制清晰的函数 框架。如果没有给出,则从第一个项目中抽取的结果 将使用帧序列。这个函数之前会被调用一次 第一帧。所需的签名是:

    def init_func() -> iterable_of_artists

    如果blit == Trueinit_func 必须返回一个可迭代的艺术家到 被重新绘制。该信息被 blitting 算法用于 确定图形的哪些部分必须更新。回报 如果是 blit == False,则 value 未使用,在这种情况下可以省略。

    如果不指定init_func,则重复第一帧(用作初始化帧)。
    也就是说,我认为避免重复的最正确方法是调用 init 函数,您不绘制任何内容:

    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    import random
    
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    
    xs = []
    ys = []
    
    def init():
        ax1.clear()
    
    def animate(i, xs, ys):
        x = i + 1
        y = random.randint(1, 50)
    
        print '{}: {}, {}'.format(i, x, y)
    
        xs.append(x)
        ys.append(y)
    
        ax1.clear()
        ax1.plot(xs, ys)
    
    
    ani = animation.FuncAnimation(fig = fig,
                                  func = animate,
                                  init_func = init,
                                  frames = 10,
                                  fargs = (xs, ys),
                                  repeat = False)
    
    plt.show()
    

    输出:

    0: 1, 12
    1: 2, 25
    2: 3, 20
    3: 4, 49
    4: 5, 49
    5: 6, 28
    6: 7, 26
    7: 8, 49
    8: 9, 10
    9: 10, 2
    

    动画:

    【讨论】:

    • 这似乎是一个可靠的解决方法。这是典型的行为吗?如果是这样,有什么原因吗?
    • 太棒了!感谢您的指导!
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多