Matplotlib を用いたマルチプロセッシング

PythonPythonBeginner
今すぐ練習

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

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、マルチプロセッシングライブラリとMatplotlibを使って、別プロセスから生成されたデータをプロットする方法を学びます。データ生成とプロットをそれぞれ担当する2つのクラス「ProcessPlotter」と「NBPlot」を作成します。「NBPlot」クラスはランダムなデータを生成し、パイプを通じて「ProcessPlotter」クラスに送信します。そして、「ProcessPlotter」クラスはそのデータをリアルタイムでプロットします。

VMのヒント

VMの起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、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 を使って、別プロセスから生成されたデータをプロットする方法を学びました。それぞれプロットとデータ生成を担当する2つのクラス ProcessPlotterNBPlot を作成しました。NBPlot クラスはランダムなデータを生成し、パイプを通じて ProcessPlotter クラスに送信し、その後でデータをリアルタイムでプロットしました。