I was trying to setup matplotlib to use interactively with wxPython as the backend. I run into the issue that when I call draw(), it blocks the interpreter. Since then I've found out it is a issue with some GUI backend that the mainloop blocks. The suggested solution is to use ipython, which I do not use for various reasons.
I think I have come across the problem stated in the user's guide: "For other user interface toolkits and their corresponding matplotlib backends, the situation is complicated by the GUI mainloop which takes over the entire process. The solution is to run the GUI in a separate thread, and this is the tricky part that ipython solves for all the major toolkits that matplotlib supports." http://matplotlib.sourceforge.net/users/shell.html#other-python-interpreters I end up spending sometime hacking some code. And I think I manage to run the interpreter and GUI mainloop in separate threads. So I'd post my code here for review and perhaps someone may find it useful. I'm very new to matplotlib so I don't know if what I do really make sense. pylab.py ------------------------------------------------------------------------ """ Run matplotlib interactively with the Python interpreter and the wxPython backend. This script launches the interpreter in a second thread while keeping matplotlib and the wxPython mainloop on the main thread. It resolves the issue that calling draw() starts the GUI mainloop and blocks the main thread. "For other user interface toolkits and their corresponding matplotlib backends, the situation is complicated by the GUI mainloop which takes over the entire process. The solution is to run the GUI in a separate thread, and this is the tricky part that ipython solves for all the major toolkits that matplotlib supports." http://matplotlib.sourceforge.net/users/shell.html#other-python-interpreters To use, just launch this script from command line, e.g c:\> python pylab.py Python 2.6.1 (r261:67517, Dec 4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. (MatplotlibConsole) >>> Alternatively it is recommended to use the Ipython shell with matplotlib. """ import code import Queue import sys import threading import matplotlib.pyplot as plt import numpy as np import wx BaseConsole = code.InteractiveConsole class MatplotlibConsole(BaseConsole): """ MatplotlibConsole is an interactive Python console that splits I/O and code execution in separate threads. This address the issue that in the Matplotlib and wxPython environment, some functions do not work well when called from an abitrary thread and should be run from the main thread only. Here code are queued instead of executed immediately. execute_queued_code() should be called regularly from the main thread. """ def __init__(self, *args): self.code_q = Queue.Queue(1) self.shutdown = False BaseConsole.__init__(self, *args) def runcode(self, code): # queue the code so that it may run in the main thread self.code_q.put(code, block=True) self.code_q.join() def execute_queued_code(self, event): if self.shutdown: # make sure shutdown action don't run more than once self.shutdown = False plt.close() return try: code = self.code_q.get_nowait() except Queue.Empty: return try: BaseConsole.runcode(self, code) finally: self.code_q.task_done() def interact(self): BaseConsole.interact(self) print 'Console Closing...' self.shutdown = True def main(argv): # instantiate MatplotlibConsole mp_locals = { "np":np, "plt":plt, } console = MatplotlibConsole(mp_locals) # launch console in a new thread shell_thread = threading.Thread(target=console.interact, name='shell_thread') shell_thread.start() # setup pyplot fig = plt.figure(1) # setup timer to run the execute_queued_code() id = wx.NewId() actor = fig.canvas.manager.frame timer = wx.Timer(actor, id=id) timer.Start(100) wx.EVT_TIMER(actor, id, console.execute_queued_code) # this doesn't work. why? # plt.ion() # show() starts the wx main loop plt.show() if __name__ =='__main__': main(sys.argv) ------------------------------------------------------------------------ There is still some issue I'm trying to solve. For some reason I don't understand I can't run plt.ion() before show(). Also I like to do an import like "from pylab import *" for the console. Wai Yip ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users