如何在对传感器进行采样时使用多重处理来绘制数据?

1 python windows matplotlib multiprocessing python-3.7

我正在尝试使用多处理 python 库在收集数据时进行绘图,并且我不想中断数据收集或减慢数据收集速度。我不确定如何存储数据并将其发送到多重处理以清晰地绘制。也不确定是否可以使用 matplotlib。

我尝试创建一个管道和一个队列。我也尝试过使用锁,但对我来说效果都不够好。我没有尝试使用 Pool,因为我没有运行很多小进程,我只是运行数据收集进程然后进行绘图。根据我对使用库的理解,您启动一​​个进程,这将使该进程启动?一旦您加入进程,它将等待返回某些内容,然后继续执行代码。我还尝试了正常的数据收集,然后添加一个单独的绘图过程,它们都是连续循环,并会因键盘中断而停止。

from multiprocessing import Process, Lock, Pipe
import time
import numpy as np
import matplotlib.pyplot as plt

def collectData(sender):
    xVal = np.random.rand() + np.random.randint(0,10)
    yval = 23 + np.random.rand()
    time.sleep(0.001)
    sender.send([xVal,yVal])

def plottingData(receiver,fig,ax):
    connect = receiver.recv()
    print(connect)
    ax.scatter(connect[0],connect[1])
    plt.show()
if __name__ == '__main__':
    fig, ax = plt.subplots()
    ax.scatter([],[])
    plt.show(block=False)

    receiver, sender = Pipe(False)

    for i in range(10):
        print('Start process...')
        duta = Process(target=collectData, args=(sender,))
        plut = Process(target=plottingData, args=(receiver,fig,ax))

        duta.start()
        plut.start()
        print('...done with process')

    duta.join()
    plut.join()
    print('Completed multiprocessing')   
Run Code Online (Sandbox Code Playgroud)

这只是一个简单的示例,我尝试编写代码来通过在它们之间传递数据来模拟数据收集和绘图。这是尝试构建的基本层。

我想做的一些事情:像我现在一样循环我的绘图。它连续运行并因键盘中断而停止。添加绘图,以便我可以看到数据,但我不想减慢数据收集速度。

根据我目前对代码的理解。这些流程希望完成然后继续,这使得连续收集变得困难。绘图也告诉了我这一点,因为我打开了 10 个单独的图形,并且直到我关闭图形窗口后它才完成。我试图传递一个 pandas 数据框然后进行绘图,但无法弄清楚是否可以通过管道或其他方式实现这一点。

任何帮助理解多处理库的帮助将不胜感激!

谢谢

Mar*_*arc 5

至于在某个过程中收集数据并将其绘制在另一个过程中,您可以执行以下操作:

from multiprocessing import Process, Queue
import time
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def collectData(communicator):
    while True:

        xval = np.random.rand() + np.random.randint(0,1)
        yval =  np.random.rand()
        communicator.put([xval,yval]) # we use the Queue here to commuicate to the other process. Any process is
        # allowed to put data into or extract data from. So the data collection process simply keeps putting data in.
        time.sleep(1) # not to overload this example ;)

def update(frame, communicator: Queue): # here frame needs to be accepted by the function since this is used in FuncAnimations
    data = communicator.get() # this blocks untill it gets some data
    xdata.append(data[0])
    ydata.append(data[1])
    ln.set_data(xdata, ydata)
    return ln,

if __name__ == '__main__':
    fig, ax = plt.subplots()
    ax.set_xlim([0, 1]) # set the limits to the values you expect
    ax.set_ylim([0, 1])
    xdata, ydata = [], []
    ln, = plt.plot([], [], 'ro')

    communicator = Queue()
    print('Start process...')
    duta = Process(target=collectData, args=(communicator,))
    duta.start()
    ani = FuncAnimation(fig, update, blit=True, fargs=(communicator,))
    plt.show()
    print('...done with process')
    duta.join()
    print('Completed multiprocessing')
Run Code Online (Sandbox Code Playgroud)

因此,我们的想法是,duta 进程不断向队列添加数据,而调用 FuncAnimation 的主初始进程不断等待,直到找到要绘制的内容。