使用 Matplotlib 进行多进程处理

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,你将学习如何使用多进程库和 Matplotlib 来绘制从单独进程生成的数据。我们将创建两个类——ProcessPlotterNBPlot——分别用于处理绘图和数据生成。NBPlot 类将生成随机数据,并通过管道将其发送到 ProcessPlotter 类,然后该类将实时绘制数据。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到笔记本标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。

导入库

我们首先导入必要的库。我们将使用 multiprocessing 来处理单独的进程,使用 time 来实现时间延迟,使用 numpy 来生成随机数据,以及使用 matplotlib 来进行绘图。

import multiprocessing as mp
import time
import numpy as np
import matplotlib.pyplot as plt

定义 ProcessPlotter

ProcessPlotter 类将处理通过管道发送的数据的绘图。它将持续检查管道中是否有新数据,并实时绘制这些数据。

class ProcessPlotter:
    def __init__(self):
        self.x = []
        self.y = []

    def terminate(self):
        plt.close('all')

    def call_back(self):
        while self.pipe.poll():
            command = self.pipe.recv()
            if command is None:
                self.terminate()
                return False
            else:
                self.x.append(command[0])
                self.y.append(command[1])
                self.ax.plot(self.x, self.y, 'ro')
        self.fig.canvas.draw()
        return True

    def __call__(self, pipe):
        print('starting plotter...')

        self.pipe = pipe
        self.fig, self.ax = plt.subplots()
        timer = self.fig.canvas.new_timer(interval=1000)
        timer.add_callback(self.call_back)
        timer.start()

        print('...done')
        plt.show()

定义 NBPlot

NBPlot 类将生成随机数据,并通过管道将其发送到 ProcessPlotter 类。

class NBPlot:
    def __init__(self):
        self.plot_pipe, plotter_pipe = mp.Pipe()
        self.plotter = ProcessPlotter()
        self.plot_process = mp.Process(
            target=self.plotter, args=(plotter_pipe,), daemon=True)
        self.plot_process.start()

    def plot(self, finished=False):
        send = self.plot_pipe.send
        if finished:
            send(None)
        else:
            data = np.random.random(2)
            send(data)

创建 NBPlot 实例并将数据发送到 ProcessPlotter

创建 NBPlot 类的实例,并将随机数据发送到 ProcessPlotter 类。我们将发送 10 组数据,每组数据之间延迟 0.5 秒。

def main():
    pl = NBPlot()
    for _ in range(10):
        pl.plot()
        time.sleep(0.5)
    pl.plot(finished=True)

if __name__ == '__main__':
    if plt.get_backend() == "MacOSX":
        mp.set_start_method("forkserver")
    main()

总结

在本实验中,我们学习了如何使用 multiprocessing 库和 Matplotlib 来绘制从单独进程生成的数据。我们创建了两个类——ProcessPlotterNBPlot——分别用于处理绘图和数据生成。NBPlot 类生成随机数据,并通过管道将其发送到 ProcessPlotter 类,然后 ProcessPlotter 类实时绘制这些数据。