views:

64

answers:

2

Hi there,

I'd like to combine interactive plotting in Matplotlib and the Command line interface Cmd in python. How can I do this? Can I use threading? I tried the following:

from cmd import Cmd
import matplotlib.pylab as plt
from threading import Thread

class MyCmd(Cmd):

    def __init__(self):
        Cmd.__init__(self)
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(1,1,1)

    def do_foo(self, arg):
        self.ax.plot(range(10))
        self.fig.canvas.draw()

if __name__=='__main__':
    c = MyCmd()
    Thread(target=c.cmdloop).start()
    plt.show()

It opens a figure window and I can type commands in the console that are actually executed. When the "foo" command is executed it draws in the figure window. So far everything is ok. When I reenter the console, however, the console seems to be stuck and there is now new command window. But when I click into the figure window the console outputs a new command prompt and I can enter a new command. It seems the two loops are not really interleaved or something. Is there a better, more common way?

A: 

I found something that works, but is rather ugly

from cmd import Cmd
import matplotlib.pylab as plt
from threading import Thread
import time

class MyCmd(Cmd):

    def __init__(self):
        Cmd.__init__(self)
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(1,1,1)

    def do_foo(self, arg):
        self.ax.plot(range(10))
        self.fig.canvas.draw()

if __name__=='__main__':
    plt.ion()
    c = MyCmd()
    def loop():
        while True:
            c.fig.canvas.draw()
            time.sleep(0.1)
    Thread(target=loop).start()
    c.cmdloop()

This simply calls the draw method of the figure periodically. If I don't do this, the figure is not redrawn, when it was occluded and comes to the front again.

But this seems ugly. Is there a better way?

Christian