我正在尝试使用OpenCV实时绘制来自摄像机的一些数据。然而,实时绘图(使用matplotlib)似乎不起作用。
我已经将问题隔离到这个简单的例子中:
fig = plt.figure()
plt.axis([0, 1000, 0, 1])
i = 0
x = list()
y = list()
while i < 1000:
temp_y = np.random.random()
x.append(i)
y.append(temp_y)
plt.scatter(i, temp_y)
i += 1
plt.show()
我希望这个例子能单独绘制1000个点。实际发生的情况是,窗口弹出,显示第一个点(可以),然后等待循环完成,然后填充图形的其余部分。
有什么想法为什么我一次看不到一个填充的点?
发布于 2013-03-31 00:37:14
以下是正在讨论的代码的工作版本(至少需要2011-11-14的Matplotlib 1.1.0版本):
import numpy as np
import matplotlib.pyplot as plt
plt.axis([0, 10, 0, 1])
for i in range(10):
y = np.random.random()
plt.scatter(i, y)
plt.pause(0.05)
plt.show()
注意对plt.pause(0.05)
的调用,它既绘制新数据又运行图形用户界面的事件循环(允许鼠标交互)。
发布于 2013-03-31 08:17:21
如果你对实时绘图感兴趣,我建议你去看看matplotlib's animation API。特别是,使用blit
避免在每一帧上重新绘制背景可以为您带来显著的速度提升(~10倍):
#!/usr/bin/env python
import numpy as np
import time
import matplotlib
matplotlib.use('GTKAgg')
from matplotlib import pyplot as plt
def randomwalk(dims=(256, 256), n=20, sigma=5, alpha=0.95, seed=1):
""" A simple random walk with memory """
r, c = dims
gen = np.random.RandomState(seed)
pos = gen.rand(2, n) * ((r,), (c,))
old_delta = gen.randn(2, n) * sigma
while True:
delta = (1. - alpha) * gen.randn(2, n) * sigma + alpha * old_delta
pos += delta
for ii in xrange(n):
if not (0. <= pos[0, ii] < r):
pos[0, ii] = abs(pos[0, ii] % r)
if not (0. <= pos[1, ii] < c):
pos[1, ii] = abs(pos[1, ii] % c)
old_delta = delta
yield pos
def run(niter=1000, doblit=True):
"""
Display the simulation using matplotlib, optionally using blit for speed
"""
fig, ax = plt.subplots(1, 1)
ax.set_aspect('equal')
ax.set_xlim(0, 255)
ax.set_ylim(0, 255)
ax.hold(True)
rw = randomwalk()
x, y = rw.next()
plt.show(False)
plt.draw()
if doblit:
# cache the background
background = fig.canvas.copy_from_bbox(ax.bbox)
points = ax.plot(x, y, 'o')[0]
tic = time.time()
for ii in xrange(niter):
# update the xy data
x, y = rw.next()
points.set_data(x, y)
if doblit:
# restore background
fig.canvas.restore_region(background)
# redraw just the points
ax.draw_artist(points)
# fill in the axes rectangle
fig.canvas.blit(ax.bbox)
else:
# redraw everything
fig.canvas.draw()
plt.close(fig)
print "Blit = %s, average FPS: %.2f" % (
str(doblit), niter / (time.time() - tic))
if __name__ == '__main__':
run(doblit=False)
run(doblit=True)
输出:
Blit = False, average FPS: 54.37
Blit = True, average FPS: 438.27
发布于 2012-08-09 07:48:57
show
可能不是最好的选择。我要做的就是使用pyplot.draw()
。您可能还希望在循环中包含一个小的时间延迟(例如,time.sleep(0.05)
),以便您可以看到绘图的发生。如果我对您的示例进行这些更改,它对我有效,我看到每个点一次出现一个。
https://stackoverflow.com/questions/11874767
复制相似问题