有没有办法分离 matplotlib 图以便计算可以继续?
在 Python 解释器中执行这些指令后,将出现一个带有绘图的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道如何在程序进行进一步计算时继续以交互方式探索由 show()
创建的图形。
有可能吗? 有时计算很长,如果在检查中间结果时继续进行计算将会有所帮助。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
使用
matplotlib
不会阻塞的调用:使用
draw()
:使用交互模式:
Use
matplotlib
's calls that won't block:Using
draw()
:Using interactive mode:
使用关键字“block”来覆盖阻止行为,例如
继续您的代码。
Use the keyword 'block' to override the blocking behavior, e.g.
to continue your code.
最好始终检查您正在使用的库是否支持以非阻塞方式使用。
但是,如果您想要一个更通用的解决方案,或者没有其他方法,您可以使用
multprocessing
模块包含在 python 中。 计算将继续:这会产生启动新进程的开销,并且有时在复杂场景下更难以调试,因此我更喜欢其他解决方案(使用
matplotlib
的 非阻塞 API 调用)It is better to always check with the library you are using if it supports usage in a non-blocking way.
But if you want a more generic solution, or if there is no other way, you can run anything that blocks in a separated process by using the
multprocessing
module included in python. Computation will continue:That has the overhead of launching a new process, and is sometimes harder to debug on complex scenarios, so I'd prefer the other solution (using
matplotlib
's nonblocking API calls)尝试
show()
文档 说:Try
The
show()
documentation says:重要:只是为了澄清一些事情。 我假设这些命令位于
.py
脚本内,并且使用例如python script.py
从控制台调用该脚本。对我有用的一个简单方法是:
script.py 文件示例:
IMPORTANT: Just to make something clear. I assume that the commands are inside a
.py
script and the script is called using e.g.python script.py
from the console.A simple way that works for me is:
Example of
script.py
file:您可能需要在
matplotlib
的文档中阅读此文档,标题为:在 python shell 中使用 matplotlib
You may want to read this document in
matplotlib
's documentation, titled:Using matplotlib in a python shell
就我而言,我希望在计算时弹出几个窗口。 作为参考,方法如下:
PS。 非常有用的matplotlib OO 接口指南 。
In my case, I wanted to have several windows pop up as they are being computed. For reference, this is the way:
PS. A quite useful guide to matplotlib's OO interface.
好吧,我在弄清楚非阻塞命令方面遇到了很大的麻烦......但最后,我设法重新设计了“Cookbook/Matplotlib/Animations - 动画选定的绘图元素”示例,因此它可以与线程一起使用(并通过全局变量或通过多进程管道在线程之间传递数据)在 Ubuntu 10.04 上的 Python 2.6.5 上。
该脚本可以在这里找到:Animating_selected_plot_elements-thread.py - 否则粘贴在下面(评论较少)以供参考:
希望这对某人有帮助,
干杯!
Well, I had great trouble figuring out the non-blocking commands... But finally, I managed to rework the "Cookbook/Matplotlib/Animations - Animating selected plot elements" example, so it works with threads (and passes data between threads either via global variables, or through a multiprocess
Pipe
) on Python 2.6.5 on Ubuntu 10.04.The script can be found here: Animating_selected_plot_elements-thread.py - otherwise pasted below (with fewer comments) for reference:
Hope this helps someone,
Cheers!
在许多情况下,将图像保存为硬盘上的 .png 文件更方便。 原因如下:
优点:
时间。
缺点:
In many cases it is more convenient til save the image as a .png file on the hard drive. Here is why:
Advantages:
time.
Drawback:
如果您在控制台(即
IPython
)中工作,您可以使用plt.show(block=False)
正如其他答案中指出的那样。 但如果你很懒,你可以直接输入:这将是相同的。
If you are working in console, i.e.
IPython
you could useplt.show(block=False)
as pointed out in the other answers. But if you're lazy you could just type:Which will be the same.
我还必须将 plt.pause(0.001) 添加到我的代码中,以使其真正在 for 循环内工作(否则它只会显示第一个和最后一个图):
I had to also add
plt.pause(0.001)
to my code to really make it working inside a for loop (otherwise it would only show the first and last plot):在我的系统上,show() 不会阻塞,尽管我希望脚本在继续之前等待用户与图形交互(并使用“pick_event”回调收集数据)。
为了阻止执行直到绘图窗口关闭,我使用了以下命令:
但是请注意,canvas.start_event_loop_default() 产生了以下警告:
尽管脚本仍在运行。
On my system show() does not block, although I wanted the script to wait for the user to interact with the graph (and collect data using 'pick_event' callbacks) before continuing.
In order to block execution until the plot window is closed, I used the following:
Note, however, that canvas.start_event_loop_default() produced the following warning:
although the script still ran.
OP 询问有关分离
matplotlib
图的问题。 大多数答案都假设命令是在 python 解释器中执行的。 这里介绍的用例是我在终端(例如 bash)中测试代码的偏好,其中运行file.py
并且您希望出现绘图但需要 python 脚本完成并返回到命令提示符。该独立文件使用
multiprocessing
启动一个单独的进程,以使用matplotlib
绘制数据。 主线程使用这篇文章。os._exit()
强制 main 退出,但让matplotlib
子进程保持活动状态并响应,直到绘图窗口关闭。 这完全是一个单独的过程。这种方法有点像 Matlab 开发会话,其中包含带有响应式命令提示符的图形窗口。 使用这种方法,您将失去与图形窗口进程的所有联系,但是,这对于开发和调试来说是可以的。 只需关闭窗口并继续测试即可。
multiprocessing
专为仅 Python 代码执行而设计,这使得它可能比subprocess
更适合。multiprocessing
是跨平台的,因此它应该可以在 Windows 或 Mac 上正常工作,只需很少或无需调整。 无需检查底层操作系统。 这是在 Linux、Ubuntu 18.04LTS 上测试的。运行
file.py
会弹出一个图形窗口,然后__main__
退出,但multiprocessing
+matplotlib
图形窗口保持响应具有缩放、平移和其他按钮,因为它是一个独立的过程。使用以下命令在 bash 命令提示符下检查进程:
ps ax|grep -v grep |grep file.py
The OP asks about detatching
matplotlib
plots. Most answers assume command execution from within a python interpreter. The use-case presented here is my preference for testing code in a terminal (e.g. bash) where afile.py
is run and you want the plot(s) to come up but the python script to complete and return to a command prompt.This stand-alone file uses
multiprocessing
to launch a separate process for plotting data withmatplotlib
. The main thread exits using theos._exit(1)
mentioned in this post. Theos._exit()
forces main to exit but leaves thematplotlib
child process alive and responsive until the plot window is closed. It's a separate process entirely.This approach is a bit like a Matlab development session with figure windows that come up with a responsive command prompt. With this approach, you have lost all contact with the figure window process, but, that's ok for development and debugging. Just close the window and keep testing.
multiprocessing
is designed for python-only code execution which makes it perhaps better suited thansubprocess
.multiprocessing
is cross-platform so this should work well in Windows or Mac with little or no adjustment. There is no need to check the underlying operating system. This was tested on linux, Ubuntu 18.04LTS.Running
file.py
brings up a figure window, then__main__
exits but themultiprocessing
+matplotlib
figure window remains responsive with zoom, pan, and other buttons because it is an independent process.Check the processes at the bash command prompt with:
ps ax|grep -v grep |grep file.py
我还希望我的图显示运行其余代码(然后继续显示),即使存在错误(我有时使用图进行调试)。 我编写了这个小技巧,以便此
with
语句中的任何绘图都具有这样的行为。这可能有点太不标准,对于生产代码来说是不可取的。 这段代码中可能有很多隐藏的“陷阱”。
如果/当我实现适当的“保持绘图打开(即使发生错误)并允许显示新绘图”时,如果没有用户干扰告诉它(用于批量执行目的),我希望脚本能够正确退出。
我可以使用类似于超时问题“脚本结束!\n如果您希望暂停绘图输出(您有 5 秒),请按 p:”来自 https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user -输入中断实施。
I also wanted my plots to display run the rest of the code (and then keep on displaying) even if there is an error (I sometimes use plots for debugging). I coded up this little hack so that any plots inside this
with
statement behave as such.This is probably a bit too non-standard and not advisable for production code. There is probably a lot of hidden "gotchas" in this code.
If/when I implement a proper "keep the plots open (even if an error occurs) and allow new plots to be shown", I would want the script to properly exit if no user interference tells it otherwise (for batch execution purposes).
I may use something like a time-out-question "End of script! \nPress p if you want the plotting output to be paused (you have 5 seconds): " from https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation.
在我看来,该线程中的答案提供的方法并不适用于每个系统以及动画等更复杂的情况。 我建议看看 MiKTeX 在以下线程中的答案,其中找到了一个可靠的方法:
如何等待matplotlib动画结束?
In my opinion, the answers in this thread provide methods which don't work for every systems and in more complex situations like animations. I suggest to have a look at the answer of MiKTeX in the following thread, where a robust method has been found:
How to wait until matplotlib animation ends?
这是我找到的最简单的解决方案(线程阻塞代码)
Here is the simplest solution I found (thread blocking code)
如果您想打开多个图形,同时保持它们全部打开,则此代码对我有用:
If you want to open multiple figures, while keeping them all opened, this code worked for me:
虽然没有直接回答 OP 的请求,但我发布了这个解决方法,因为它可能会帮助遇到这种情况的人:
为此,我使用:
其中“var”标识循环中的绘图,因此它不会被覆盖。
While not directly answering OPs request, Im posting this workaround since it may help somebody in this situation:
for this Im using:
Where "var" identifies the plot in the loop so it wont be overwritten.
我发现最好的解决方案是在最后显示所有图,这样程序就不会等待您关闭图形并将所有图放在一起以便您可以并排检查它们。
但这样你就无法在程序运行时检查绘图。
What I have found as the best solution so the program does not wait for you to close the figure and have all your plots together so you can examine them side by side is to show all the plots at the end.
But this way you cannot examine the plots while program is running.
使用
plt.show(block=False)
,并在脚本末尾调用plt.show()
。这将确保脚本完成后窗口不会关闭。
Use
plt.show(block=False)
, and at the end of your script callplt.show()
.This will ensure that the window won't be closed when the script is finished.