1

我正在尝试使用 matplotlib->FuncAnimate 函数为图形设置动画。但是,我无法理解 Blit 的工作原理。对于每一帧,我只想在旧数据点之上绘制新数据点。它说使用 Blit 它应该只自动更新更改的值。因此,如果我打开它(blit=True),以前的数据点应该保留在我的图中。但这种情况并非如此。以前的数据被删除,图形从头开始重绘。

在文档中,它说我必须返回“iterable_of_artists”,算法将知道哪些数据已更改。我只想传递新数据并在旧数据之上绘制。顺便说一句,什么是“iterable_of_artists”,它只是一个可以绘制的对象列表吗?如果有人能指出我的定义,我将不胜感激。

无论如何,我已经研究了几个显示奇怪行为的基本示例。在第一个示例中,我将 Blit=True 设置为使用 animate 函数仅绘制新数据。这在理论上应该在旧数据之上绘制,但事实并非如此,只绘制新数据。

import time
import random
import numpy
import matplotlib 
import matplotlib.pyplot as pyplot
from matplotlib.animation import FuncAnimation

def livePlot():
     
    fig, ax = pyplot.subplots(1,1)
    ax = pyplot.axes(xlim=(0, 2), ylim=(0, 100))
    line, = ax.plot([], [], 'ro') #ax.plot will return a tupple

    def init():
        line.set_data(0, 50)
        return line,  #Return is not necessary when blit=False

    def animate(frame):
        x = frame
        y = random.randint(0, 100)
        line.set_data(x,y)
        return line, #Return is not necessary when blit=False
        
    animation = FuncAnimation(
        fig, animate, 
        init_func = init, 
        frames= [0.5, 1, 1.5, 2.0], 
        interval=1000, 
        repeat=False, 
        blit=True, # Turning on Blit
        cache_frame_data = True) 
    
    pyplot.show()

if __name__ == "__main__":
    livePlot()

我能够通过欺骗 FuncAnimate 方法来实现我的目标。我可以使用斧头并在每一帧中绘制新数据。如果我这样做,旧数据将保留,仅绘制新数据。但是,我可以使用 Blit=True 或 Blit=False 来做到这一点,它没有任何效果。因此,我对 Blit 的工作原理以及仅绘制新数据而无需创建包含所有要绘制的数据的列表的正确方法感到非常困惑。如果我有很长的数据点集,则传递一个大列表将在内存中创建一个大变量。这是我的解决方法,但我不确定这是否是正确的方法,或者是否有更好的方法使用 Blit=True 并重新绘制新数据。

import time
import random
import numpy
import matplotlib 
import matplotlib.pyplot as pyplot
from matplotlib.animation import FuncAnimation

def livePlot():
     
    fig, ax = pyplot.subplots(1,1)
    ax = pyplot.axes(xlim=(0, 2), ylim=(0, 100))

    def init():
        ax.plot(0, 50, 'ro')
        return []

    def animate(frame):
        x = frame
        y = random.randint(0, 100)
        ax.plot(x, y, 'ro') # plotting directly on the axis. This keeps the old data
        return [] # fooling the blit algorithm with an empty stream
        
    animation = FuncAnimation(
        fig, animate, 
        init_func = init, 
        frames= [0.5, 1, 1.5, 2.0], 
        interval=1000, 
        repeat=False, 
        blit=True,
        cache_frame_data = True) 
        
    pyplot.show() 

if __name__ == "__main__":
    livePlot()
4

0 回答 0