繁体   English   中英

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

[英]How can I use multiprocessing to plot data while sampling sensors?

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

我试图创建一个管道和一个队列。 我也尝试过使用锁,但都没有对我有效。 我不尝试使用Pool,因为我没有运行很多小程序,而是在运行数据收集程序然后进行绘图。 根据我对库的了解,您可以启动一个Process,然后才能启动该过程? 加入流程后,它将等待直到返回某些内容,然后在代码中继续进行。 我还尝试了正常的数据收集,然后添加了一个单独的绘图过程,它们都是连续循环,会因KeyboardInterrupt而停止。

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

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

我正在尝试做的一些事情:像现在一样循环绘图。 它连续运行并通过KeyboardInterrupt停止。 加上绘图功能,这样我就可以看到数据,但我不想减慢数据收集速度。

从到目前为止我对代码的理解。 流程正在寻求完成,然后继续进行,从而使连续收集变得困难。 绘图也告诉了我这一点,因为我打开了10个单独的图形,并且直到关闭图形窗口后才能完成。 我正在尝试传递一个熊猫数据框,然后进行绘制,无法确定是否可以通过管道或其他方式进行绘制。

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

谢谢

如果要连续接收和绘制数据,则可能需要使用多线程和matplotlib的FuncAnimation工具。 设置一个线程以接收数据并将其以某种形式存储在列表中,然后在动画功能中更新线/散点图的值以查看反映在图上的更改。 确保动画在程序的主循环中运行,否则可能会导致问题。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM