如何使用matplotlib绘制日志文件的实时更新?

时间:2016-02-22 22:53:07

标签: python animation numpy logging matplotlib

到目前为止,这是我的代码:

with open(logfile,'rb') as f:

    while True:
        lines = sum(1 for line in f)
        print lines
        X = np.arange(lines)
        data = []
        for line in f:
            a = line.split(',')
            data.append(a[1][:-2])
        print data
        Y = np.array(data)
        plt.ion()
        graph = plt.plot(X,Y)[0]
        graph.set_y_data(Y)
        plt.plot(data)
        plt.draw()
        plt.pause(0.01)

现在,当我打印数据或Y时,它会打印一个空数组。然后,它抱怨X当然与Y的维度不同。我想知道是否这可能是因为在调用print命令之前数据填充不够快?但是python应该按顺序执行,对吗?

无论如何,我认为这里的逻辑可能是错误的。这是我最好的猜测 - 打开文件,然后在True中,尝试阅读所有内容并将其发送到plot.draw使用的图中。然后,随着日志文件的增长,文件正在增长,图表数据和图表本身将会更新。我怎样才能确保这有效?

1 个答案:

答案 0 :(得分:2)

使用matplotlibs动画功能

您需要animation这样example

更新数据的版本

首先创建一个空图并沿途更新:

import time

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


def read(logfile):
    with open(logfile) as f:
        data = []
        while True:
            line = f.readline()
            time.sleep(0.1)
            if line:
                data.append(float(line.split(',')[1][:-2]))
                yield data

def animate(values):
    x = list(range(len(values)))
    line.set_data(x, values)
    ax.set_xlim(x[0], x[-1])
    ax.set_ylim(min(values), max(values))
    return line,

fig, ax = plt.subplots()
line, = ax.plot([])


ani = FuncAnimation(fig, animate, frames=read('log.txt'), interval=10)
plt.show()

每次创建新图表的版本

代码较少,但仅适用于几个步骤:

import time

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


def read(logfile):
    with open(logfile) as f:
        data = []
        while True:
            line = f.readline()
            time.sleep(0.1)
            if line:
                data.append(float(line.split(',')[1][:-2]))
                yield data

def animate(values):
    line, = plt.plot(values, color='blue')
    return line,

fig = plt.figure(figsize = (5,5))

ani = FuncAnimation(fig, animate, frames=read('log.txt'), interval=10)
plt.show()