Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exit on KeyboardInterrupt after generating plots in while loop

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.

like image 950
Nik Hartman Avatar asked Jan 07 '13 16:01

Nik Hartman


People also ask

How do I use KeyboardInterrupt in Python?

In Python, there is no special syntax for the KeyboardInterrupt exception; it is handled in the usual try and except block. The code that potentially causes the problem is written inside the try block, and the 'raise' keyword is used to raise the exception, or the python interpreter raises it automatically.


1 Answers

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.

like image 152
Nik Hartman Avatar answered Oct 05 '22 17:10

Nik Hartman