使用Matplotlib创建CSV数据的实时图

MBl*_*eld 4 python csv matplotlib python-3.x

我试图使用Matplotlib可视化一些测量.测量通常持续约24小时,并将包括csv中约30k行的数据.我一直在努力让我的情节实际上是动画.我可以执行代码,它会显示一个截至当前时间点的快照,但不会显示任何其他内容.当我尝试自动缩放它时,没有任何绘图,它只是在两个轴上默认为-.6到+.6的视图.我应该调用plt.draw()来实现这个目的吗?这是我到目前为止:

import numpy as np
import datetime as dt
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import animation

FMT = '%Y-%m-%d %H:%M:%S.%f'
data = np.genfromtxt('sampleData.csv', delimiter=',', skip_header=5,
                 names=['x', 'y', 'z', 'w'], dtype=['object', 'int8', 'int8', 'float'])                  

mytime = [dt.datetime.strptime(i.decode('ascii'), FMT) for i in data['x']]
thickness = data['w']

fig = plt.figure()
axes = fig.add_subplot(111)
line, = axes.plot([], [], '.')
plt.show(block=False)

def init():
    line.set_data([],[]) 
    return line,

fig.canvas.draw()

def animate(i):
    xdata = mytime[:i]
    ydata = thickness[:i]
    line.set_data(xdata, ydata)
    plt.draw()
    axes.relim()
    axes.autoscale(True,'both',True) 
    axes.autoscale_view(True,True,True)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,  
                           interval=0, blit=True)

plt.show()
Run Code Online (Sandbox Code Playgroud)

这是来自CSV的示例数据行:

2013-09-25 14:51:15.329091,1,0,439.80,,,,0,0,
Run Code Online (Sandbox Code Playgroud)

Joe*_*ton 11

你有两个问题.一个是因为你有效地绘制了两次东西,第二个是纯粹的人类心理学(随着时间的推移,情节看起来会变慢,因为你将一点加到10000而将一个点加到10或100).


让我们先讨论双抽:

FuncAnimation将借鉴的东西给你,但是告诉它使用位图传输,它只是更新的轴,而不是蜱等的内部.因此,你需要手动调用draw,但动画将被调用draw_artist,以及.

你应该能够通过删除blit=True和至少获得2倍的加速plt.draw()

此外,通过设置interval=0,你强迫它不断绘制,这将有效地迫使事情锁定.将间隔设置为更合理的值,例如25(间隔以毫秒为单位."25"为40 fps.).

例如,这对我来说非常顺利:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation

y = np.random.normal(0, 1, 10000).cumsum(axis=0)
x = np.arange(y.size)

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

def init():
    line.set_data(x[:2],y[:2])
    return line,

def animate(i):
    i = min(i, x.size)
    xdata = x[:i]
    ydata = y[:i]
    line.set_data(xdata, ydata)
    ax.relim()
    ax.autoscale()
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=25)

plt.show()
Run Code Online (Sandbox Code Playgroud)

我还添加了ax.margins(0.05)以避免轴限制捕捉到下一个最接近的"偶数"数字并给出"生涩"的外观.


但是,由于您正在逐步绘制越来越多的数据,因此变化率似乎会变慢,因为较少的数据似乎会随着时间的推移而变化.在10000的末尾添加一个点几乎不可察觉,但在10的末尾添加一个点是非常明显的.

因此,情节看起来很多更"精彩"的开头比,即使它更新以同样的速度结束.

这与matplotlib没有任何关系,这是您选择动画数据的方式的结果.

为了解决这个问题,您可以考虑在数据中移动"滑动窗口"并一次绘制一个恒定数量的点.举个例子:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation

y = np.random.normal(0, 1, 1000000).cumsum(axis=0)
x = np.arange(y.size) + 1

fig, ax = plt.subplots()
line, = ax.plot([], [], 'k-')
ax.margins(0.05)

def init():
    line.set_data(x[:2],y[:2])
    return line,

def animate(i):
    win = 300
    imin = min(max(0, i - win), x.size - win)
    xdata = x[imin:i]
    ydata = y[imin:i]
    line.set_data(xdata, ydata)
    ax.relim()
    ax.autoscale()
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=25)

plt.show()
Run Code Online (Sandbox Code Playgroud)