Параллельное программирование jupyter windows
Задача такая:
Есть некоторая функция get_data, которая непрерывно добавляет в датафрейм значения. Чтобы особо не грузить подробностями, опишу функцию, которая просто добавляет по 2 значения из готовых массивов с некоторым временным интервалом
%matplotlib qt5
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import time
freqs = np.arange(1, 1000, 1)
currents = np.arange(1, 1000, 1)
frame = pd.DataFrame({'x_value': [],
'y_value': []})
x_ind = 0
y_ind = 0
def get_data():
global x_ind, y_ind, frame
try:
while x_ind != len(currents):
new_line = {'x_value': currents[x_ind],
'y_value': freqs[y_ind]}
frame = frame.append(new_line, ignore_index=True)
x_ind += 1
y_ind += 1
time.sleep(1)
except KeyboardInterrupt:
pass
Есть и 2 функция, которая все это в реальном времени анимирует и обновляет окошко с графиком (Бэкенд matplotlib - qt5) раз в 3 секунды
"""Функция для анимации"""
n = 0
def animate(self):
global n
x = frame['x_value'].values
y = frame['y_value'].values
plt.plot(x,y, label=f'{n}')
plt.legend()
n += 1
"""Сама анимация"""
def animation():
ani = FuncAnimation(plt.gcf(), animate, interval=3000)
plt.show()
try:
while len(plt.get_fignums()) > 0:
plt.pause(0.1)
except:
plt.close('all')
Мне бы хотелось, чтобы эти 2 функции (get_data и animation) выполнялись одновременно. Я уже понял, что библиотека Multiprocessing не дружит с юпитером. Пробовал также и библиотеку Multiprocess с конструкцией
#! pip install multiprocess
from multiprocess import Process
if __name__ == "__main__":
p1 = Process(target=get_data)
p2 = Process(target=animation)
p1.start()
p2.start()
p1.join()
p2.join()
она не сработала. Ячейка просто моментально выполнилась и все.
Далее я начал пробовать библиотеку ipyparallel. Установил ее
conda install ipyparallel
Активировал кластерное расширение
ipcluster nbextension enable --user
И попытался запустить процесс следующим образом
from ipyparallel import Client
rc = Client()
res1 = rc[0].apply(get_data)
res2 = rc[1].apply(animation)
res1.get()
res2.get()
Вроде как оно пытается выполниться, но все равно выдает ошибку
---------------------------------------------------------------------------NameError Traceback (most recent call last)<string> in <module>
<ipython-input-4-e2b3ae0513f5> in get_data()
NameError: name 'x_ind' is not defined
Как я понимаю, ipyparallel работает, только если в функции инкапсулированно описание абсолютно всех переменных и функций, если таковые используются.
Опять же, это игрушечный пример, который я попытался написать на основе своей основной программы. Там чуть больше глобальных переменных и сами функции более громоздкие.
Мне бы хотелось понять, как можно реализовать параллельное выполнение таких громоздких функций в юпитере.