7

I wish to run a simulation while at the same time output its progress in a plot. I've been looking through a lot of examples of threading and multiprocessing, but they are all pretty complex. So I thought with Python's new asyncio library this should be easier.

I found an example (How to use 'yield' inside async function?) and modified it for my cause:

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() 

Question

I added a simple plt.show() and the program still freezes. I thought with asyncio I could run it in parallel? Obviously my knowledge is still lacking. An example that does the following would be really helpful:

  • Add a line to a plot (of matplotlib) everytime async_generator returns a value.

1 Answer 1

7

First of all, I misunderstood asyncio, it doesn't make run things in parallel (use asyncio for parallel tasks).

It seems the only thing that worked for me was plt.pause(0.001) (Plotting in a non-blocking way with Matplotlib). plt.draw() opened a window, but it didn't show anything and plt.show freezes the program. It seems that plt.show(block=False) is deprecated and using plt.ion gives the problem that the final result closes when the program is finished. Also await asyncio.sleep(0.1) didn't make the plot draw a line.

Working code

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() 

Notes

  • You get however a deprecated message: 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), which you can suppress with: warnings.filterwarnings().

  • I'm not sure if asyncio was actually necessary for my use case...

  • Difference between threading and multiprocessing for who's interested: Multiprocessing vs Threading Python

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.