Introdução
Neste laboratório, você aprenderá como usar a biblioteca multiprocessing e o Matplotlib para plotar dados gerados a partir de um processo separado. Criaremos duas classes - ProcessPlotter e NBPlot - para lidar com a plotagem e a geração de dados, respectivamente. A classe NBPlot gerará dados aleatórios e os enviará para a classe ProcessPlotter através de um pipe, que então plotará os dados em tempo real.
Dicas para a VM
Após a inicialização da VM, clique no canto superior esquerdo para mudar para a aba Notebook e acessar o Jupyter Notebook para praticar.
Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.
Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão, e resolveremos o problema prontamente para você.
Importar Bibliotecas
Começamos importando as bibliotecas necessárias. Usaremos multiprocessing para lidar com os processos separados, time para o atraso de tempo, numpy para gerar dados aleatórios e matplotlib para a plotagem.
import multiprocessing as mp
import time
import numpy as np
import matplotlib.pyplot as plt
Definir a Classe ProcessPlotter
A classe ProcessPlotter lidará com a plotagem dos dados enviados através do pipe. Ela verificará continuamente o pipe em busca de novos dados e os plotará em tempo real.
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()
Definir a Classe NBPlot
A classe NBPlot gerará dados aleatórios e os enviará para a classe ProcessPlotter através de um pipe.
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)
Criar uma instância de NBPlot e enviar dados para ProcessPlotter
Crie uma instância da classe NBPlot e envie dados aleatórios para a classe ProcessPlotter. Enviaremos 10 conjuntos de dados, com um atraso de 0,5 segundos entre cada conjunto.
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()
Resumo
Neste laboratório, aprendemos como usar a biblioteca multiprocessing e Matplotlib para plotar dados gerados a partir de um processo separado. Criamos duas classes - ProcessPlotter e NBPlot - para lidar com a plotagem e a geração de dados, respectivamente. A classe NBPlot gerou dados aleatórios e os enviou para a classe ProcessPlotter através de um pipe, que então plotou os dados em tempo real.