【问题标题】:asyncio matplotlib show() still freezes programasyncio matplotlib show() 仍然冻结程序
【发布时间】:2017-10-25 02:32:53
【问题描述】:

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

我找到了一个示例 (How to use 'yield' inside async function?) 并出于我的原因对其进行了修改:

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 可以并行运行它?显然我的知识还不够。 执行以下操作的示例将非常有帮助:

  • 每次async_generator 返回一个值时,向(matplotlib)绘图添加一条线。

【问题讨论】:

    标签: python python-3.x matplotlib python-asyncio


    【解决方案1】:

    首先,我误解了 asyncio,它不能并行运行 (use asyncio for parallel tasks)。

    似乎唯一对我有用的是plt.pause(0.001) (Plotting in a non-blocking way with Matplotlib)。 plt.draw() 打开了一个窗口,但没有显示任何内容,plt.show 冻结了程序。似乎plt.show(block=False) 已被弃用,使用plt.ion 会导致程序完成时最终结果关闭的问题。 await asyncio.sleep(0.1) 也没有让情节画线。

    工作代码

    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: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation),您可以使用:warnings.filterwarnings() 隐藏它。

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

    • threadingmultiprocessing 之间的区别:Multiprocessing vs Threading Python

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2016-06-13
      • 1970-01-01
      相关资源
      最近更新 更多