Python 如何使用matplotlib在while循环中实时绘图?

Python 如何使用matplotlib在while循环中实时绘图?,python,matplotlib,while-loop,real-time,Python,Matplotlib,While Loop,Real Time,我正在尝试使用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(

我正在尝试使用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()
fig=plt.figure()
plt.轴([0,1000,0,1])
i=0
x=列表()
y=列表()
当我<1000时:
temp_y=np.random.random()
x、 附加(i)
y、 附加(临时)
plt.散射(i,温度)
i+=1
plt.show()
我希望这个例子能分别画出1000个点。实际发生的情况是,窗口弹出并显示第一个点(可以),然后等待循环完成,然后再填充图的其余部分


有没有想过为什么我没有看到一次填充一个点?

问题似乎是您希望
plt.show()
显示窗口,然后返回。但事实并非如此。程序将在该点停止,仅在关闭窗口后恢复。您应该能够测试这一点:如果您关闭窗口,然后会弹出另一个窗口

要解决这个问题,只需在循环后调用
plt.show()
。然后你得到完整的情节。(但不是“实时绘图”)


您可以尝试如下设置关键字参数
block
plt.show(block=False)
一次,然后用于更新。

show
可能不是最好的选择。我要做的是改用
pyplot.draw()
。您可能还希望在循环中包含一个小的时间延迟(例如,
time.sleep(0.05)
),以便可以看到正在发生的绘图。如果我对您的示例进行这些更改,我会看到每个点一次出现一个。

以下是相关代码的工作版本(至少需要2011-11-14版本的Matplotlib 1.1.0):


请注意调用
plt.pause(0.05)
,它既绘制新数据又运行GUI的事件循环(允许鼠标交互)。

如果您对实时绘图感兴趣,我建议您研究一下。特别是,使用
blit
避免在每一帧上重新绘制背景,可以显著提高速度(~10倍):


我知道这个问题由来已久,但现在GitHub上有一个名为“PythonDrawNow”的包。这提供了一个类似于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)

PythonDrawNow是一个围绕plt.draw的薄型包装,但提供了在图形显示后确认(或调试)的功能。

没有一种方法适合我。 但我找到了这个

您只需添加

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
导入matplotlib.pyplot作为plt
将numpy作为np导入
请注意这个更正
图=plt.图()
plt.轴([01000,0,1])
i=0
x=列表()
y=列表()

而我如果你想画图,而不是在画更多的点时冻结你的线程,你应该使用plt.pause()而不是time.sleep()

我正在使用以下代码绘制一系列xy坐标

import matplotlib.pyplot as plt 
import math


pi = 3.14159

fig, ax = plt.subplots()

x = []
y = []

def PointsInCircum(r,n=20):
    circle = [(math.cos(2*pi/n*x)*r,math.sin(2*pi/n*x)*r) for x in xrange(0,n+1)]
    return circle

circle_list = PointsInCircum(3, 50)

for t in range(len(circle_list)):
    if t == 0:
        points, = ax.plot(x, y, marker='o', linestyle='--')
        ax.set_xlim(-4, 4) 
        ax.set_ylim(-4, 4) 
    else:
        x_coord, y_coord = circle_list.pop()
        x.append(x_coord)
        y.append(y_coord)
        points.set_data(x, y)
    plt.pause(0.01)

这是我在我的系统上使用的一个版本

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

def makeFig():
    plt.scatter(xList,yList) # I think you meant this

plt.ion() # enable interactivity
fig=plt.figure() # make a figure

xList=list()
yList=list()

for i in np.arange(50):
    y=np.random.random()
    xList.append(i)
    yList.append(y)
    drawnow(makeFig)
    #makeFig()      The drawnow(makeFig) command can be replaced
    #plt.draw()     with makeFig(); plt.draw()
    plt.pause(0.001)

drawnow(makeFig)线可以替换为makeFig();plt.draw()序列,它仍然可以正常工作。

我知道我回答这个问题有点晚了。尽管如此,我还是在不久前编写了一些代码来绘制实时图形,我想与大家分享:

PyQt4的代码:

###################################################################
#                                                                 #
#绘制活动图(PyQt4)#
#                  -----------------------------                  #
#将MATPLOTLIB动画嵌入到#
#自己的GUI#
#                                                                 #
###################################################################
导入系统
导入操作系统
从PyQt4导入QtGui
从PyQt4导入QtCore
导入功能工具
将numpy作为np导入
将随机导入为rd
导入matplotlib
matplotlib.use(“Qt4Agg”)
从matplotlib.figure导入图形
从matplotlib.animation导入时间信息
从matplotlib.lines导入Line2D
从matplotlib.backends.backend_qt4agg导入FigureCanvas qtagg as FigureCanvas
导入时间
导入线程
def setCustomSize(x、宽度、高度):
sizePolicy=QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(x.sizePolicy().hasHeightForWidth())
x、 设置大小策略(大小策略)
x、 setMinimumSize(QtCore.QSize(宽度、高度))
x、 setMaximumSize(QtCore.QSize(宽度、高度))
''''''
类CustomMainWindow(QtGui.QMainWindow):
定义初始化(自):
超级(CustomMainWindow,self)。\uu初始化
#定义主窗口的几何图形
self.setGeometry(300300800400)
self.setWindowTitle(“我的第一个窗口”)
#创建一个框架
self.FRAME_A=QtGui.QFrame(self)
self.FRAME_A.setStyleSheet(“QWidget{background color:%s}”%QtGui.QColor(210210235255.name())
self.LAYOUT_A=QtGui.QGridLayout()
self.FRAME_A.setLayout(self.LAYOUT_A)
self.setCentralWidget(self.FRAME_A)
#放置缩放按钮
self.zoomBtn=QtGui.QPushButton(文本='zoom')
setCustomSize(self.zoomBtn,100,50)
self.zoomBtn.clicked.connect(self.zoomBtn操作)
self.LAYOUT\u A.addWidget(self.zoomBtn,*(0,0))
#放置matplotlib图形
self.myFig=CustomFigCanvas()
self.LAYOUT\u A.addWidget(self.myFig,*(0,1))
#将callbackfunc添加到。。
myDataLoop=threading.Thread(名称='myDataLoop',目标=dataSendLoop,daemo
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
import matplotlib.pyplot as plt 
import math


pi = 3.14159

fig, ax = plt.subplots()

x = []
y = []

def PointsInCircum(r,n=20):
    circle = [(math.cos(2*pi/n*x)*r,math.sin(2*pi/n*x)*r) for x in xrange(0,n+1)]
    return circle

circle_list = PointsInCircum(3, 50)

for t in range(len(circle_list)):
    if t == 0:
        points, = ax.plot(x, y, marker='o', linestyle='--')
        ax.set_xlim(-4, 4) 
        ax.set_ylim(-4, 4) 
    else:
        x_coord, y_coord = circle_list.pop()
        x.append(x_coord)
        y.append(y_coord)
        points.set_data(x, y)
    plt.pause(0.01)
import matplotlib.pyplot as plt
from drawnow import drawnow
import numpy as np

def makeFig():
    plt.scatter(xList,yList) # I think you meant this

plt.ion() # enable interactivity
fig=plt.figure() # make a figure

xList=list()
yList=list()

for i in np.arange(50):
    y=np.random.random()
    xList.append(i)
    yList.append(y)
    drawnow(makeFig)
    #makeFig()      The drawnow(makeFig) command can be replaced
    #plt.draw()     with makeFig(); plt.draw()
    plt.pause(0.001)
from datetime import datetime
from matplotlib import pyplot
from matplotlib.animation import FuncAnimation
from random import randrange

x_data, y_data = [], []

figure = pyplot.figure()
line, = pyplot.plot_date(x_data, y_data, '-')

def update(frame):
    x_data.append(datetime.now())
    y_data.append(randrange(0, 100))
    line.set_data(x_data, y_data)
    figure.gca().relim()
    figure.gca().autoscale_view()
    return line,

animation = FuncAnimation(figure, update, interval=200)

pyplot.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro')

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)
plt.show()
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
import time
import psutil
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

i = 0
x, y = [], []

while True:
    x.append(i)
    y.append(psutil.cpu_percent())

    ax.plot(x, y, color='b')

    fig.canvas.draw()

    ax.set_xlim(left=max(0, i - 50), right=i + 50)
    fig.show()
    plt.pause(0.05)
    i += 1