6

I am monitoring an experiment in real time using matplotlib to generate plots in a while loop. Ideally, the loop should exit on something like a KeyboardInterrupt. This works well enough in an Ubuntu test. In Windows 7, using ipython, it exits with "Terminate batch job (Y/N)?" then closes the interpreter. I would like to avoid this behavior and leave the interpreter open after the KeyboardInterrupt. Here is a test script.

[EDIT 2]: This script works fine in Windows if ipython is loaded as ipython --pylab.

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!'

[EDIT 1]: I should be more clear why I tagged this with matplotlib. The below example script executes with no problems in either operating system.

i = 0 
start = time.time()
while True:
    try:
        data = [time.time() - start, np.random.rand()]
        print ' '.join('{:.2f}'.format(x) for x in data)
        time.sleep(0.1)
    except KeyboardInterrupt:
        print "Proram ended by user. \n"
        break
print 'Success!'

All of the packages were installed yesterday as part of a clean installation of Enthought.

Nik Hartman
  • 123
  • 1
  • 9
  • Part of the issue is specifically that `plt.pause` is not interruptible while there is a figure drawn (not a Windows-specific bug). I would recommend bringing this up as a [matplotlib Issue](https://github.com/matplotlib/matplotlib/issues) – minrk Jan 09 '13 at 21:15

2 Answers2

1

Right now the best way I've found to solve this problem across several Windows machines is as follows...

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!'

Unfortunately, this is not at all platform independent, but everything I've read over the past few days leads me to believe that platform-independent keyboard input is not really achievable. The code in my original question works well in Unix and some Windows installations. This code works well in the few Windows installations I've tried. All of this works best when run through ipython --pylab. This might have to be good enough for now.

Nik Hartman
  • 123
  • 1
  • 9
0

I cannot reproduce your problem. I copied your test script in a file ipythonexception.py and started it from ipython with the run command. Then I get the following output.

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]:

Everything seems to work as it should do. I'm on Windows 7, Python 2.7.2 and Ipython 0.13.

Do you start Ipython with a batch file? I tink "Terminate batch job (Y/N)?" is a Windows message I usually get if I break some batch jobs.

Holger
  • 2,125
  • 2
  • 19
  • 30
  • I suspect this problem has something to do with the way `Enthought` and `ipython` work together. I also could not reproduce the problem outside of my Enthought installation. It seems that Enthought might open ipython as part of a batch script. When opening with `ipython --pylab` I don't get a `"Terminate batch job (Y/N)?"` message immediately after running that test script, but I do get the message upon quitting ipython with `quit()`. I think this link may be related: [link](http://wiki.ipython.org/Cookbook/Interrupting_threads) – Nik Hartman Jan 08 '13 at 15:26
  • I did confirm this on a second Enthought installation in our lab. This one is on an XP SP3 machine. It seems like the best answer for this is to just avoid using KeyboardInterrupt to end the program. – Nik Hartman Jan 08 '13 at 19:09