使用Matplotlib创建CSV数据的实时图 [英] Creating a live plot of CSV data with Matplotlib

查看:981
本文介绍了使用Matplotlib创建CSV数据的实时图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Matplotlib来显示一些测量。测量通常持续约24小时,并将在csv中包括〜30k行数据。我一直在努力,主要是让我的地块实际上动画。我可以执行代码,它将显示一个快照,直到当前时间点,但没有别的。当我尝试自动缩放时,没有绘图,它默认为在两个轴上的视图-.6到+6。我应该调用plt.draw()为此工作?这是我到目前为止:

I am trying to use Matplotlib to visualize some measurements. The measurements typically last about 24hrs and will include ~30k lines of data in the csv. I've been struggling mostly with getting my plots to actually animate. I can execute the code and it will display a snapshot up to the current point in time but nothing else. When I try to autoscale it, nothing plots and it just defaults to a view of -.6 to +.6 on both axes. Am I supposed to call plt.draw() for this to work? This is what I have so far:

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()

这是CSV中的一个示例数据行:

This is a sample line of data from the CSV:

2013-09-25 14:51:15.329091,1,0,439.80,,,,0,0,


推荐答案

您有两个问题。一个是因为你有效地绘制了两次,第二个是纯粹的人类心理学(情节似乎慢了一段时间,因为你添加一点到10000,而添加一点到10或100)。

You have two issues. One is because you're effectively drawing things twice, the second is purely human psychology (the plot appears to slow over time because you're adding one point to 10000 vs adding one point to 10 or 100).

让我们先讨论双重绘制:

Let's discuss the double-draw first:

FuncAnimation 将为你绘制东西,但通过告诉它使用blitting,它只是更新轴的内部而不是更新ticks等。因此,你需要手动调用 draw ,但是动画将调用 draw_artist

The FuncAnimation will draw things for you, but by telling it to use blitting, it's only updating the inside of the axes and not the ticks, etc. Therefore, you need to manually call draw, but the animation will be calling draw_artist, as well.

您应该可以通过删除 blit = True plt.draw()

You should be able to get at least a 2x speedup by removing blit=True and plt.draw()

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

Furthermore, by setting interval=0, you're forcing it to draw constantly, which will effectively force things to lock up. Set the interval to something more reasonable, e.g. 25 (the interval is in milliseconds. "25" is 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()

我也添加了 ax.margins ),以避免轴限制贴紧到下一个最近的偶数数字,并给出干燥的外观。

I've also added ax.margins(0.05) to avoid the axes limits snapping to the next nearest "even" number and giving a "jerky" appearance.

但是,由于您越来越多地绘制越来越多的数据, ,因为较少的数据似乎随时间而变化。在10000结束时添加一个点几乎不显着,但是在10结束时添加一个点是非常可见。

However, because you're progressively plotting more and more data, the rate of change will appear to slow, simply because less of the data appears to be changing over time. Adding one point at the end of 10000 is hardly noticeable, but adding one point at the end of 10 is very noticable.

这没有任何东西,因为它在开始时比起结束时更多地令人兴奋做与matplotlib,并且是您选择为您的数据设置动画的结果。

This has nothing whatsoever to do with matplotlib, and is a consequence of the way you're choosing to animate your data.

为了解决这个问题,你可以考虑在你的数据中移动一个滑动窗口,同时绘制一个恒定的点数。例如:

To get around that, you might consider moving a "sliding window" through your data and plotting a constant number of points at a time. As an example:

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()

这篇关于使用Matplotlib创建CSV数据的实时图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆