asyncio matplotlib show() 仍然冻结程序 [英] asyncio matplotlib show() still freezes program

查看:92
本文介绍了asyncio matplotlib show() 仍然冻结程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望运行模拟,同时在同一时间在绘图中输出其进度.我一直在研究许多线程和多处理示例,但是它们都很复杂.所以我认为使用 Python 的新 asyncio 库应该会更容易.

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.

我找到了一个示例(如何在异步函数内部使用"yield"?) 并根据我的原因对其进行了修改:

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

问题

我添加了一个简单的 plt.show() 并且程序仍然冻结.我想使用 asyncio 可以并行运行它吗?显然我的知识仍然缺乏.执行以下操作的示例将非常有帮助:

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:

  • 每次 async_generator 返回一个值时,向(matplotlib 的)绘图添加一条线.
  • Add a line to a plot (of matplotlib) everytime async_generator returns a value.

推荐答案

首先,我误解了 asyncio,它不会并行运行(将 asyncio 用于并行任务).

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

似乎唯一对我有用的是 plt.pause(0.001) (使用 Matplotlib 以非阻塞方式绘图).plt.draw() 打开了一个窗口,但没有显示任何内容,plt.show 冻结了程序.似乎不推荐使用 plt.show(block=False) 并且使用 plt.ion 会出现程序完成时最终结果关闭的问题.同样, await asyncio.sleep(0.1)并没有使绘图画线.

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.

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

注释

  • 然而,您收到一条已弃用的消息:python3.6/site-packages/matplotlib/backend_bases.py:2445:MatplotlibDeprecationWarning:使用默认事件循环,直到实现特定于此 GUI 的功能warnings.warn(str, mplDeprecation),你可以用它来抑制:warnings.filterwarnings().

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

      我不确定 asyncio 对于我的用例是否真的有必要...

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

      threadingmultiprocessing 之间的区别对于感兴趣的人:多处理与线程 Python

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

      这篇关于asyncio matplotlib show() 仍然冻结程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆