如何在Python中运行脚本时操纵数字?

now*_*wox 11 python matplotlib

介绍

当我来自,我习惯于一个交互式界面,脚本可以在运行时更新数字.在处理期间,每个图形可以重新调整大小或甚至关闭.这可能意味着每个数字都在自己的线程中运行,这显然不是的情况.

IPython可以使用magic命令模仿Matlab行为,%pylab或者%matplotlib做一些我还不了解的事情,这是我的问题的重点.

我的目标是允许独立的Python脚本像Matlab一样工作(或者像IPython %matplotlib一样工作).换句话说,我希望从命令行执行此脚本.我期待每3秒弹出一个新的数字.在执行期间,我可以缩放,调整大小甚至关闭图形.

#!/usr/bin/python
import matplotlib.pyplot as plt
import time

def do_some_work(): 
    time.sleep(3)

for i in range(10):
    plt.plot([1,2,3,4])
    plt.show() # this is way too boilerplate, I'd like to avoid it too. 
    do_some_work()
Run Code Online (Sandbox Code Playgroud)

%matplotlib当脚本在Python(而不是IPython)中运行时,我可以用什么替代方法来操作数字?

我已经调查了哪些解决方案?

我目前找到3种方式来获得情节表演.

1. %pylab/%matplotlib

正如汤姆所说,%pylab应该避免使用,以防止名称空间被污染.

>>> %pylab
>>> plot([1,2,3,4])
Run Code Online (Sandbox Code Playgroud)

这个解决方案是甜的,情节是非阻塞的,不需要额外的show(),我仍然可以添加一个网格,grid()然后我可以关闭,调整大小或放大我的数字,没有其他问题.

不幸的是,该%matplotlib命令仅在IPython上可用.

2. from pylab import *from matplotlib.pyplot import plt

>>> from pylab import *
>>> plot([1,2,3,4])
Run Code Online (Sandbox Code Playgroud)

这里情况完全不同.我需要添加命令show()来显示阻塞的数字.我无法做任何事情,只是关闭图形来执行下一个命令,例如grid()由于图现在关闭所以没有效果...

**3. from pylab import *from matplotlib.pyplot import plt+ ion()**一些建议建议使用如下ion()命令:

>>> from pylab import *
>>> ion()
>>> plot([1,2,3,4])
>>> draw()
>>> pause(0.0001)
Run Code Online (Sandbox Code Playgroud)

不幸的是,即使情节显示,我也无法手动关闭数字.我需要close()在不太方便的终端上执行.此外,需要两个额外的命令,如draw(); pause(0.0001)我所期待的.

摘要

%pylab,一切都很棒,但我不能在IPython之外使用它

随着from pylab import *接着是plot,我得到一个阻止行为和IPython的所有的力量被浪费.

from pylab import *接下来ion提供了一个很好的替代前一个,但我必须使用奇怪的pause(0.0001)命令导致一个我无法手动关闭的窗口(我知道pause一些后端不需要.我正在使用WxAgg哪个是唯一一个效果很好Cygwin x64.

这个问题建议使用matplotlib.interactive(True).不幸的是,它不起作用,并给出了相同的行为ion().

tit*_*jan 7

将您的do_some_work功能更改为以下,它应该工作.

def do_some_work(): 
    plt.pause(3)
Run Code Online (Sandbox Code Playgroud)

对于交互式后端,plt.pause(3)启动事件循环3秒钟,以便它可以处理您的调整大小事件.请注意,文档说它是一个实验函数,对于复杂的动画,您应该使用动画模块.

这些%pylab%matplotlib魔术命令也会启动事件循环,这就是用户与绘图交互的原因.或者,您可以使用启动事件循环%gui wx,然后将其关闭%gui.您可以使用IPython.lib.guisupport.is_event_loop_running_wx()函数来测试它是否正在运行.

使用ion()或的原因ioff()"什么是交互模式"页面中得到了很好的解释.原则上,没有IPython就可以进行用户交互.但是,我无法从该页面获取交互式示例以使用Qt4Agg后端,仅使用MacOSX后端(在我的Mac上).我没有尝试使用WX后端.

编辑

我确实通过使用PyQt4而不是PySide来设置交互式示例以使用Qt4Agg后端(因此通过backend.qt4 : PyQt4在我的~/.config/matplotlibrc文件中设置).我认为该示例不适用于所有后端.我在这里提交了一个问题.

编辑2

我担心在长时间计算运行时不能使用线程来操纵图形的方法.正如你所提到的:Matplotlib不会启动一个线程,也不会启动IPython.%pylab和%matplotlib命令在处理来自read-eval-print循环的命令之间交替,并让GUI处理事件的时间很短.他们按顺序这样做.

事实上,即使使用%matplotlib或%pylab魔法,我也无法重现您的行为.(只是要清楚:在ipython我第一次打电话%matplotlib然后%run yourscript.py).%matplotlib魔术将Matplotlib置于交互模式,这使得plt.show()调用无阻塞,从而do_some_work立即执行该函数.然而,在time.sleep(3)通话期间,该数字没有响应(如果我增加睡眠时间,这变得更加明显).我不明白这是如何在你的最后工作.

除非我错了,否则你必须在较小的部分中分解你的计算并使用plt.pause(甚至更好的动画模块)来更新数字.