asyncio matplotlib show () todavía se congela progtwig

Deseo ejecutar una simulación mientras que al mismo tiempo muestro su progreso en un gráfico . He estado viendo muchos ejemplos de subprocesos y multiprocesamiento, pero todos son bastante complejos. Así que pensé que con la nueva biblioteca de asyncio Python esto debería ser más fácil.

Encontré un ejemplo ( ¿Cómo usar ‘rendimiento’ dentro de la función asíncrona? ) Y lo modifiqué para mi causa:

 import matplotlib.pyplot as plt import asyncio import numpy as np class DataAnalysis(): def __init__(self): # asyncio so we can plot data and run simulation in parallel loop = asyncio.get_event_loop() try: loop.run_until_complete(self.plot_reward()) finally: loop.run_until_complete( loop.shutdown_asyncgens()) # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.shutdown_asyncgens loop.close() async def async_generator(self): for i in range(3): await asyncio.sleep(.4) yield i * i async def plot_reward(self): # Prepare the data x = np.linspace(0, 10, 100) # Plot the data plt.plot(x, x, label='linear') #plt.show() # add lines to plot async for i in self.async_generator(): print(i) # Show the plot plt.show() if __name__ == '__main__': DataAnalysis() 

Pregunta

plt.show() un simple plt.show() y el progtwig todavía se congela. Pensé con asyncio que podría ejecutarlo en paralelo? Obviamente, mi conocimiento sigue faltando. Un ejemplo que haga lo siguiente sería realmente útil:

  • Agregue una línea a un gráfico (de matplotlib ) cada vez que async_generator devuelva un valor.

En primer lugar, no entendí asyncio, no hace que se ejecuten cosas en paralelo ( usar asyncio para tareas paralelas ).

Parece que lo único que funcionó para mí fue plt.pause(0.001) ( trazar de forma no bloqueante con Matplotlib ). plt.draw() abrió una ventana, pero no mostró nada y plt.show congela el progtwig. Parece que plt.show(block=False) está en desuso y el uso de plt.ion da el problema de que el resultado final se cierra cuando finaliza el progtwig. También await asyncio.sleep(0.1) no hizo que la ttwig dibujara una línea.

Código de trabajo

 import matplotlib.pyplot as plt import asyncio import matplotlib.cbook import warnings warnings.filterwarnings("ignore",category=matplotlib.cbook.mplDeprecation) class DataAnalysis(): def __init__(self): # asyncio so we can plot data and run simulation in parallel loop = asyncio.get_event_loop() try: loop.run_until_complete(self.plot_reward()) finally: loop.run_until_complete( loop.shutdown_asyncgens()) # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.shutdown_asyncgens loop.close() # keep plot window open plt.show() async def async_generator(self): for i in range(3): await asyncio.sleep(.4) yield i * i async def plot_reward(self): #plt.ion() # enable interactive mode # receive dicts with training results async for i in self.async_generator(): print(i) # update plot if i == 0: plt.plot([2, 3, 4]) elif i == 1: plt.plot([3, 4, 5]) #plt.draw() plt.pause(0.1) #await asyncio.sleep(0.4) if __name__ == '__main__': da = DataAnalysis() 

Notas

  • Sin embargo, recibe un mensaje en desuso: python3.6/site-packages/matplotlib/backend_bases.py:2445: MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation) , que puede suprimir con: warnings.filterwarnings() .

  • No estoy seguro de si asyncio fuera realmente necesario para mi caso de uso …

  • Diferencia entre threading y multiprocessing para quién está interesado: multiproceso vs subprocesamiento de Python