我正在尝试使用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个点。实际发生的情况是,窗口弹出,显示第一个点(好吧),然后等待循环结束,然后填充图的其余部分。
有什么想法,为什么我没有看到点填充一个时间?
这些方法对我都没用。
但我找到了这个
实时matplotlib图仍然在循环中不工作
你所需要做的就是添加
plt.pause(0.0001)
然后你可以看到新的地块。
所以你的代码应该是这样的,它可以工作
import matplotlib.pyplot as plt
import numpy as np
plt.ion() ## Note this correction
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()
plt.pause(0.0001) #Note this correction
我知道这个问题很老了,但是现在在GitHub上有一个叫做“python-drawnow”的包。这提供了一个类似于MATLAB的drawnow的界面——您可以轻松地更新图形。
用例示例:
import matplotlib.pyplot as plt
from drawnow import drawnow
def make_fig():
plt.scatter(x, y) # I think you meant this
plt.ion() # enable interactivity
fig = plt.figure() # make a figure
x = list()
y = list()
for i in range(1000):
temp_y = np.random.random()
x.append(i)
y.append(temp_y) # or any arbitrary update to your figure's data
i += 1
drawnow(make_fig)
Python-drawnow是围绕plt的一个薄包装。绘图,但提供了图形显示后确认(或调试)的能力。
下面是问题代码的工作版本(至少需要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)的调用,它既绘制新数据,又运行GUI的事件循环(允许鼠标交互)。
另一种选择是使用散景。在我看来,至少对于实时情节来说,这是一个不错的选择。下面是问题中代码的散景版本:
from bokeh.plotting import curdoc, figure
import random
import time
def update():
global i
temp_y = random.random()
r.data_source.stream({'x': [i], 'y': [temp_y]})
i += 1
i = 0
p = figure()
r = p.circle([], [])
curdoc().add_root(p)
curdoc().add_periodic_callback(update, 100)
对于运行它:
pip3 install bokeh
bokeh serve --show test.py
Bokeh通过websocket通信在web浏览器中显示结果。当数据由远程无头服务器进程生成时,它尤其有用。