问题描述
我希望运行模拟,同时在同一时间在绘图中输出其进度.我一直在研究许多线程和多处理示例,但是它们都很复杂.所以我认为使用 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
) everytimeasync_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 implementedwarnings.warn(str, mplDeprecation)
, which you can suppress with:warnings.filterwarnings()
.我不确定
asyncio
对于我的用例是否真的有必要...I'm not sure if
asyncio
was actually necessary for my use case...threading
和multiprocessing
之间的区别对于感兴趣的人:多处理与线程 PythonDifference between
threading
andmultiprocessing
for who's interested: Multiprocessing vs Threading Python这篇关于asyncio matplotlib show() 仍然冻结程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!