Python 在while循环中生成绘图后退出键盘中断

Python 在while循环中生成绘图后退出键盘中断,python,windows,matplotlib,ipython,enthought,Python,Windows,Matplotlib,Ipython,Enthought,我正在使用matplotlib实时监控一个实验,以生成while循环中的绘图。理想情况下,循环应该以类似于键盘中断的方式退出。这在Ubuntu测试中效果很好。在Windows 7中,使用ipython,它会退出“终止批处理作业(Y/N)?”,然后关闭解释器。我希望避免这种行为,并在键盘中断后让解释器打开。这是一个测试脚本 [编辑2]:如果将ipython加载为ipython--pylab,则此脚本在Windows中工作正常 import time import numpy as np impor

我正在使用matplotlib实时监控一个实验,以生成while循环中的绘图。理想情况下,循环应该以类似于
键盘中断的方式退出。这在Ubuntu测试中效果很好。在Windows 7中,使用
ipython
,它会退出
“终止批处理作业(Y/N)?”
,然后关闭解释器。我希望避免这种行为,并在键盘中断后让解释器打开。这是一个测试脚本

[编辑2]:如果将
ipython
加载为
ipython--pylab,则此脚本在Windows中工作正常

import time
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([0], [0], 'b-o')

window = 50
plot_data = np.zeros((window, 2))

i = 0
start = time.time()
while True:
    try:
        data = [time.time() - start, np.random.rand()]
        print ' '.join('{:.2f}'.format(x) for x in data)
        if i < window:
            plot_data[i,:] = data
            line.set_data(plot_data[0:i+1,0], plot_data[0:i+1,1])
        else:
            plot_data[0:window-1] = plot_data[1:window]
            plot_data[window-1] = data
            line.set_data(plot_data[:,0], plot_data[:,1])
        ax.relim()
        ax.autoscale_view(True,True,True)
        fig.canvas.draw()
        plt.pause(0.1)
        i += 1
    except KeyboardInterrupt:
            print "Program ended by user.\n"
            break 
print 'Success!'

所有的软件包都是昨天安装的,作为
enthund

的干净安装的一部分,我无法重现您的问题。我在文件
ipythonexception.py
中复制了您的测试脚本,并使用
run
命令从
ipython
启动它。然后我得到以下输出

In [1]: run ipythonexception.py
0.00 0.27
0.31 0.11
0.56 0.44
0.81 0.26
1.06 0.27
1.29 0.66
1.53 0.32
1.76 0.74
2.03 0.44
2.26 0.89
Program ended by user.

Success!

In [2]: window
Out[2]: 50

In [3]:
一切似乎都正常运转。我使用的是
windows7
python2.7.2
ipython0.13


您是否使用批处理文件启动
Ipython
?我修补
“终止批处理作业(Y/N)”
是一条
Windows
消息,如果我中断一些批处理作业,通常会收到该消息。

目前,我发现跨多台Windows计算机解决此问题的最佳方法如下所示

print 'press \'q\' to end run'
time.sleep(1.0)

fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([0], [0], 'b-o')

window = 150
plot_data = np.zeros((window, 2))

i = 0
start = time.time()
while True:
    data = [time.time() - start, np.random.rand()]
    print ' '.join('{:.2f}'.format(x) for x in data)
    if i < window:
        plot_data[i,:] = data
        line.set_data(plot_data[0:i+1,0], plot_data[0:i+1,1])
    else:
        plot_data[0:window-1] = plot_data[1:window]
        plot_data[window-1] = data
        line.set_data(plot_data[:,0], plot_data[:,1])
    ax.relim()
    ax.autoscale_view(True,True,True)
    fig.canvas.draw()
    plt.pause(delay)
    i += 1
    if msvcrt.kbhit():
        if ord(msvcrt.getch()) == 113:
            print "Program ended by user.\n"
            break 
print 'Success!'
打印“按'q\'结束运行”
时间。睡眠(1.0)
图=plt.图()
ax=图添加_子批次(111)
直线,=ax.绘图([0],[0],'b-o')
窗口=150
绘图数据=np.0((窗口,2))
i=0
开始=时间。时间()
尽管如此:
数据=[time.time()-start,np.random.rand()]
打印“”。连接(“{.2f}”。数据中x的格式(x)
如果我不在窗口:
绘图数据[i,:]=数据
行设置数据(绘图数据[0:i+1,0],绘图数据[0:i+1,1])
其他:
绘图数据[0:window-1]=绘图数据[1:window]
绘图数据[window-1]=数据
line.set_数据(绘图数据[:,0],绘图数据[:,1])
ax.relim()
ax.自动缩放视图(真、真、真)
图canvas.draw()
plt.暂停(延迟)
i+=1
如果msvcrt.kbhit():
如果ord(msvcrt.getch())==113:
打印“程序已由用户结束。\n”
打破
打印“成功!”

不幸的是,这并不是完全独立于平台的,但我在过去几天里读到的所有内容都让我相信,独立于平台的键盘输入并不是真正可以实现的。我最初问题中的代码在Unix和一些Windows安装中运行良好。这段代码在我尝试过的几个Windows安装中运行良好。所有这些在通过
ipython--pylab
运行时效果最好。现在这可能已经足够好了。

我怀疑这个问题与
enthunk
ipython
的合作方式有关。我也无法在我热情的安装之外重现这个问题。看来Enthound可能会将ipython作为批处理脚本的一部分打开。使用
ipython--pylab打开时,在运行该测试脚本后,我不会立即收到
消息“终止批处理作业(Y/N)”
,但在使用
quit()退出ipython时,我会收到消息。我认为这个链接可能与此相关:我在实验室的第二次安装中确认了这一点。这一次安装在XP SP3机器上。似乎最好的解决办法是避免使用键盘中断来结束程序。问题的一部分是当绘制图形时,
plt.pause
不可中断(不是Windows特有的错误)。我建议把这个作为一个例子提出来
print 'press \'q\' to end run'
time.sleep(1.0)

fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([0], [0], 'b-o')

window = 150
plot_data = np.zeros((window, 2))

i = 0
start = time.time()
while True:
    data = [time.time() - start, np.random.rand()]
    print ' '.join('{:.2f}'.format(x) for x in data)
    if i < window:
        plot_data[i,:] = data
        line.set_data(plot_data[0:i+1,0], plot_data[0:i+1,1])
    else:
        plot_data[0:window-1] = plot_data[1:window]
        plot_data[window-1] = data
        line.set_data(plot_data[:,0], plot_data[:,1])
    ax.relim()
    ax.autoscale_view(True,True,True)
    fig.canvas.draw()
    plt.pause(delay)
    i += 1
    if msvcrt.kbhit():
        if ord(msvcrt.getch()) == 113:
            print "Program ended by user.\n"
            break 
print 'Success!'