2

我正在编写一个带有散布图和计算的 python 脚本。我对 matplotlib 的行为,尤其是plt.pause. 考虑以下片段:

import matplotlib.pyplot as plt
import time
fig,ax=plt.subplots()
ax.plot([1,2])
fig.show()
time.sleep(5) #This is a substitute for real computations

-> 五秒钟内没有任何反应

import matplotlib.pyplot as plt
import time
fig,ax=plt.subplots()
ax.plot([1,2])
plt.pause(0.1)
fig.show()
time.sleep(5) #This is a substitute for real computations

-> 窗口显示所需的绘图五秒钟

似乎plt.pause需要看到任何东西。那么为什么文档会说“这个功能是实验性的;它的行为可能会在未来的版本中改变或扩展。” 为什么我没有plt.pause在任何教程中看到?

另外,为什么如此重要的功能会被设计得如此奇怪,以至于用户必须输入足够小的时间,而不是零?我知道有些人实际上想暂停执行,但我没有,我只是想看看情节。这有那么不寻常吗?


顺便说一句,我注意到我也可以这样做plt.show(),由于我不知道的原因,它的行为不同于plt.gcf().show()[= fig.show] 并阻止执行,直到用户关闭窗口。虽然这确实在我想要的时候显示了情节,但我不希望停止执行,我希望用户在后续计算期间继续看到情节。使用plt.show(block=False)DOES 似乎表现得像plt.gcf().show()[= fig.show()],所以它也是没用的。

此外,我在某个地方读到了plt.ion应该有帮助的地方,但没有。在上面的片段中添加plt.ion()beforefig,ax=plt.subplots()不会改变任何东西。

最后,我听说不同的后端可能会有不同的行为。我在 Ubuntu 18 上使用 python 3.6 (anaconda) 和 matplotlib 2.2.2。如果我import matplotlib; matplotlib.use('Qt5Agg')在片段的开头添加,没有太大的变化,而是第一个片段在五秒钟内没有显示任何内容,而是在五秒钟内显示一个垃圾窗口(窗口显示屏幕上弹出的位置显示的任何内容) .

4

1 回答 1

4

文档plt.pause()

暂停间隔秒。
如果有活动图形,它将在暂停之前更新并显示,并且 GUI 事件循环(如果有)将在暂停期间运行。
这可以用于粗略的动画。有关更复杂的动画,请参阅 matplotlib.animation。

因此pause将实际draw的数字。

“必需”的关键plt.pause是它启动了模型事件循环,以便它有时间至少运行一次并完整地生成图形。之后,您的代码可以继续。代码运行时,不会处理更多事件。因此,该图可能会显得没有反应。这意味着您应该pause在之后反复调用以不让窗口冻结。通过这种方式,您可以模拟事件循环,同时仍然能够在其间运行其他代码。

plt.pause()在这个例子中提到了,它做了上面描述的事情。

fig.show()不运行事件循环。所以没有运行的事件循环,没有pause它只会显示图形窗口;但如果你不给任何时间处理任何事件,它会立即冻结。在这里,您可能会遇到操作系统和后端之间的差异。也许您只看到窗口边框而没有在其间绘制任何东西,或者您可能会看到工具栏和白色表面。

一般来说,所有这一切的关键是理解python(像其他编程语言一样)线性处理代码。想要运行事件循环(即响应式 GUI 窗口)以及并行执行的其他一些代码的愿望与此原则相矛盾。避免这种情况的常用方法是在不同的线程中运行任何其他代码。但是,matplotlib 无法知道那是什么代码以及如何将其同步到主线程。因此,这种解决方案将需要用户实施。

于 2018-12-13T11:35:15.377 回答