Matplotlib创建实时动画图表

11
我在设置代码以创建实时动画图表方面遇到了困难。我的代码是在收集数据后绘制图形,而不是在每次迭代时显示图形。我的脚本运行回归函数,然后将其存储在文件中,然后我访问这些文件并绘制它们。以下是我所拥有的内容,请问我需要移动或更改什么才能实现实时绘图呢?我已尝试将绘图函数移动到for循环内,但没有成功,您有什么建议吗?
 fig = plt.figure()
 ax1 = fig.add_subplot(1,1,1)

 num = 10 
 for idx in range(1,num):
    c,e = Regr_magic()
        with open("CK_output.txt",'a') as CK:
            CK.write("{0},{1}\n".format(idx,c))
        with open("error_output.txt",'a') as E:
            E.write("{0},{1}\n".format(idx,e))



    def animate(i):
        pull = open('error_output.txt','r').read()
        data = pull.split('\n')
        xar = []
        yar = []

        for each in data:
            if len(each)>1:
                x,y = each.split(',')
                xar.append(float(x))
                yar.append(float(y))
            ax1.plot(xar, yar)
    ani = animation.FuncAnimation(fig, animate, interval=1000)
    plt.show()

提供信息,数据文件包含以下内容:迭代次数和Ck值或错误,因此它们看起来像这样:

1,.0554
2,.0422
3,.0553
4,.0742
5,.0232
1个回答

16

预计算结果的解决方案

这将从输出文件中的数据生成一个不错的动画:

from matplotlib import pyplot as plt
from matplotlib import animation


fig = plt.figure()

with open('error_output.txt') as fobj:
    x, y = zip(*([float(x) for x in line.split(',')] for line in fobj))


def animate(n):
    line, = plt.plot(x[:n], y[:n], color='g')
    return line,

anim = animation.FuncAnimation(fig, animate, frames=len(x), interval=1000)
plt.show()

实时动画解决方案,数据计算后立即生成动画

这是一个版本,可以实时动画显示regr_magic生成的数据:

import random
import time

from matplotlib import pyplot as plt
from matplotlib import animation


class RegrMagic(object):
    """Mock for function Regr_magic()
    """
    def __init__(self):
        self.x = 0
    def __call__(self):
        time.sleep(random.random())
        self.x += 1
        return self.x, random.random()

regr_magic = RegrMagic()

def frames():
    while True:
        yield regr_magic()

fig = plt.figure()

x = []
y = []
def animate(args):
    x.append(args[0])
    y.append(args[1])
    return plt.plot(x, y, color='g')


anim = animation.FuncAnimation(fig, animate, frames=frames, interval=1000)
plt.show()

RegrMagic是一个辅助类,用于模拟Regr_magic()__call__ 方法使得该类的实例表现得像一个函数。它具有状态并产生数字1, 0.56565, 2, 0.65566等,每个调用都会产生(第二个数字是随机数)。它还具有时间延迟以模拟计算时间。

重要的是frames()。将Regr_magic()替换为RegrMagic(),就可以进行操作了。

解决这个具体问题的方法

一个没有模拟的版本:

import random
import time

from matplotlib import pyplot as plt
from matplotlib import animation


def frames():
    while True:
        yield Regr_magic()


fig = plt.figure()

x = []
y = []
def animate(args):
    x.append(args[0])
    y.append(args[1])
    return plt.plot(x, y, color='g')


anim = animation.FuncAnimation(fig, animate, frames=frames, interval=1000)
plt.show()

谢谢!现在我知道我缺少什么了,这个能够实时工作吗?当数据文件被追加新数据时。 - octain
2
那需要一些更改。frames需要成为一个生成器,逐个产生值。 - Mike Müller
我不确定如何做,我不熟悉Python中的yield。但是我需要将x作为yield返回吗? - octain
另外,您使用“Class”重要吗?因为我的回归函数 c, e=Regr_magic() 是一个返回两个不同变量的函数。 - octain
1
这个类只是一个辅助工具,你可以抛弃它并使用你的函数:yield Regr_magic()。注意大写字母 R - Mike Müller
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接