Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asyncio matplotlib show() still freezes program

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.
like image 544
NumesSanguis Avatar asked May 24 '17 16:05

NumesSanguis


1 Answers

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

like image 136
NumesSanguis Avatar answered Sep 28 '22 05:09

NumesSanguis