在 Python 中运行脚本时如何操作数字? [英] How to manipulate figures while a script is running in Python?

查看:62
本文介绍了在 Python 中运行脚本时如何操作数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

由于我来自,我用于交互式界面,脚本可以在脚本运行时更新图形.在处理过程中,每个图形都可以调整大小,甚至可以关闭.这可能意味着每个图形都在自己的线程中运行,而 .

IPython 可以使用魔术命令 %pylab%matplotlib 模仿 Matlab 的行为,它们做了一些我还不明白的事情,这正是我的重点问题.

我的目标是允许独立的 Python 脚本像 Matlab 一样工作(或像带有 %matplotlib 的 IPython 那样工作).换句话说,我希望从命令行执行此脚本.我希望每3秒就会弹出一个新数字.在执行过程中,我将能够缩放,调整大小甚至关闭图形.

#!/usr/bin/python导入matplotlib.pyplot作为plt导入时间def do_some_work():time.sleep(3)对于范围内的我(10):plt.plot([1,2,3,4])plt.show() # 这太像样板了,我也想避免它.做一些工作()

<块引用>

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

我已经研究过哪些解决方案?

我目前发现了三种显示情节的方式.

1.%pylab/%matplotlib

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

 >>>%pylab>>>情节([1,2,3,4])

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

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

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

 >>>从 pylab 导入 *>>>情节([1,2,3,4])

这里的情况大不相同.我需要添加命令 show() 来显示我的阻塞图形.除了关闭图形以执行下一个命令(如 grid())外,我什么也不能做,因为该图形现已关闭...

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

 >>>从 pylab 导入 *>>>离子()>>>情节([1,2,3,4])>>>画()>>>暂停(0.0001)

不幸的是,即使绘图显示,我也无法手动关闭图形.我需要在终端上执行 close() 这不是很方便.此外,还需要两个额外的命令,例如 draw();暂停(0.0001)不是我所期望的.

总结

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

使用pylab import * 中的,然后加上 plot ,我得到了阻止行为,并且IPython的所有功能都被浪费了.

from pylab import * 后跟 ion 为前一个提供了一个不错的替代方案,但我必须使用奇怪的 pause(0.0001)命令会导致无法手动关闭的窗口(我知道某些后端不需要 pause .我使用的是 WxAgg ,这是唯一可以使用的窗口在 Cygwin x64 上很好.

问题建议使用 matplotlib.interactive(True).不幸的是,它不起作用,并且具有与 ion()相同的行为.

解决方案

将您的 do_some_work 函数更改为以下内容,它应该可以工作了.

  def do_some_work():请暂停(3)

对于交互式后端 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后端一起工作(因此,通过在我的〜/.config/中设置 backend.qt4:PyQt4 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 (甚至更好的是,动画模块)来更新图形.

Introduction

As I am coming from , I am used to an interactive interface where a script can update figures while it is running. During the processing each figure can be re-sized or even closed. This probably means that each figure is running in its own thread which is obviously not the case with .

IPython can imitate the Matlab behavior using the magic command %pylab or %matplotlib which does something that I don't understand yet and which is the very point of my question.

My goal is then to allow standalone Python scripts to work as Matlab does (or as IPython with %matplotlib does). In other words, I would like this script to be executed from the command line. I am expecting a new figure that pop-up every 3 seconds. During the execution I would be able to zoom, resize or even close the figure.

#!/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()

What alternative to %matplotlib I can use to manipulate figures while a script is running in Python (not IPython)?

What solutions I've already investigated?

I currently found 3 way to get a plot show.

1. %pylab / %matplotlib

As tom said, the use of %pylab should be avoided to prevent the namespace to be polluted.

>>> %pylab
>>> plot([1,2,3,4])

This solution is sweet, the plot is non-blocking, there is no need for an additionnal show(), I can still add a grid with grid() afterwards and I can close, resize or zoom on my figure with no additional issues.

Unfortunately the %matplotlib command is only available on IPython.

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

>>> from pylab import *
>>> plot([1,2,3,4])

Things are quite different here. I need to add the command show() to display my figure which is blocking. I cannot do anything but closing the figure to execute the next command such as grid() which will have no effect since the figure is now closed...

** 3. from pylab import * or from matplotlib.pyplot import plt + ion()** Some suggestions recommend to use the ion() command as follow:

>>> from pylab import *
>>> ion()
>>> plot([1,2,3,4])
>>> draw()
>>> pause(0.0001)

Unfortunately, even if the plot shows, I cannot close the figure manually. I will need to execute close() on the terminal which is not very convenient. Moreover the need for two additional commands such as draw(); pause(0.0001) is not what I am expecting.

Summary

With %pylab, everything is wonderful, but I cannot use it outside of IPython

With from pylab import * followed by a plot, I get a blocking behavior and all the power of IPython is wasted.

from pylab import * followed by ion offers a nice alternative to the previous one, but I have to use the weird pause(0.0001) command that leads to a window that I cannot close manually (I know that the pause is not needed with some backends. I am using WxAgg which is the only one that works well on Cygwin x64.

This question advices to use matplotlib.interactive(True). Unfortunately it does not work and gives the same behavior as ion() does.

解决方案

Change your do_some_work function to the following and it should work.

def do_some_work(): 
    plt.pause(3)

For interactive backends plt.pause(3) starts the event loop for 3 seconds so that it can process your resize events. Note that the documentation says that it is an experimental function and that for complex animations you should use the animation module.

The, %pylab and %matplotlib magic commands also start an event loop, which is why user interaction with the plots is possible. Alternatively, you can start the event loop with %gui wx, and turn it off with %gui. You can use the IPython.lib.guisupport.is_event_loop_running_wx() function to test if it is running.

The reason for using ion() or ioff() is very well explained in the 'What is interactive mode' page. In principle, user interaction is possible without IPython. However, I could not get the interactive-example from that page to work with the Qt4Agg backend, only with the MacOSX backend (on my Mac). I didn't try with the WX backend.

Edit

I did manage to get the interactive-example to work with the Qt4Agg backend by using PyQt4 instead of PySide (so by setting backend.qt4 : PyQt4 in my ~/.config/matplotlibrc file). I think the example doesn't work with all backends. I submitted an issue here.

Edit 2

I'm afraid I can't think of a way of manipulating the figure while a long calculation is running, without using threads. As you mentioned: Matplotlib doesn't start a thread, and neither does IPython. The %pylab and %matplotlib commands alternate between processing commands from the read-eval-print loop and letting the GUI processing events for a short time. They do this sequentially.

In fact, I'm unable to reproduce your behavior, even with the %matplotlib or %pylab magic. (Just to be clear: in ipython I first call %matplotlib and then %run yourscript.py). The %matplotlib magic puts Matplotlib in interactive-mode, which makes the plt.show() call non-blocking so that the do_some_work function is executed immediately. However, during the time.sleep(3) call, the figure is unresponsive (this becomes even more apparent if I increase the sleeping period). I don't understand how this can work at your end.

Unless I'm wrong you'll have to break up your calculation in smaller parts and use plt.pause (or even better, the animation module) to update the figures.

这篇关于在 Python 中运行脚本时如何操作数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆