はじめに
この実験では、マルチプロセッシングライブラリと 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 つのクラス ProcessPlotter と NBPlot を作成しました。NBPlot クラスはランダムなデータを生成し、パイプを通じて ProcessPlotter クラスに送信し、その後でデータをリアルタイムでプロットしました。