From: John H. <jdh...@ac...> - 2003-12-29 16:24:08
|
>>>>> "Jeremy" == Jeremy O'Donoghue <je...@o-...> writes: Jeremy> I can say that in the original design, the intention was Jeremy> that show() would be the last line of any script. I know Jeremy> that John (author of virtually everything in Matplotlib Jeremy> except backend_wx) has recently made some changes to allow Jeremy> show() to be called more than once. Jeremy> Unfortunately, the code needed to do thisis quite specific Jeremy> to each GUI library, and I cannot simply port what has Jeremy> been done for GTK (I've just tried something very close to Jeremy> the GTK implementation, and it doesn't work). Jeremy> A few questions for John Hunter: I think I need to do Jeremy> something like the following: - show() must now Jeremy> instantiate any figures already defined and enter the the Jeremy> main event loop. ShowOn needs to keep track of this. - I Jeremy> need to keep track of the number of figures Jeremy> instantiated. I assume that Gcf.destroy() does this. - I Jeremy> need to ensure that I do not exit when the last figure is Jeremy> destroyed, and therefore need to manage that I may need to Jeremy> create a new figure manager if there is none. Hi Jeremy, I think we should consider redoing this whole segment of the code from the ground up to make for a cleaner / cross GUI implementation. It may be that Pearu Peteson <pe...@ce...> gui_thread code is the way to go for this since that is what is was designed to do (enable interactive control of WX plots (chaco) from the shell). He has indicated a willingness to port it to pygtk provided we're willing to help test his code with the WX and GTK matplotlib backends. However, this would create a scipy dependency... But let me give a little overview of why the code is currently the way it is. When the use calls 'show' it realizes all the figures and sets self.show = on This is a critical part, because the function draw_if_interactive (which is called by every matplotlib.matlab command) only draws if this variable is set def draw_if_interactive(): if ShowOn().get(): figManager = Gcf.get_active() if figManager is not None: fig = figManager.figure fig.draw() fig.queue_draw() The point I want to emphasize is that the primary reason there is a difference between interactive and batch mode is for efficiency. In interactive mode, the entire figure must be redrawn with each command (eg, setting an xlabel, changing a ticklabel property, etc...). This can get quite expensive when you want to set a lot of properties. Thus the default 'batch mode' defers all the drawing operations until the end for efficiency, and just makes one draw. I don't think the current architecture for show, draw_if_interactive, ShowOn etc, is very elegant or easily understandable, and would be happy to refactor it for the next release. Ideally we could handle these two cases across backends 1) defer all drawing until a call to show, which draws and realizes all pending figures. This should not hang the script, ie, further drawing commands should be possible. 2) do drawing with each matplotlib.matlab command for interactive mode (current implementation in backend_gtk with ShowOn.set(1) at start of script) For the most part, I think we have this with the GTK backend, but it may be necessary to refactor in order to get something that works with both. I'll think it over and take a look at the WX code to see if I get any ideas how to proceed. In the meantime, we should also see if we can get matplotlib to work with gui_thread -- I'll take a look at this too. JDH |