You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(33) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(7) |
Feb
(44) |
Mar
(51) |
Apr
(43) |
May
(43) |
Jun
(36) |
Jul
(61) |
Aug
(44) |
Sep
(25) |
Oct
(82) |
Nov
(97) |
Dec
(47) |
2005 |
Jan
(77) |
Feb
(143) |
Mar
(42) |
Apr
(31) |
May
(93) |
Jun
(93) |
Jul
(35) |
Aug
(78) |
Sep
(56) |
Oct
(44) |
Nov
(72) |
Dec
(75) |
2006 |
Jan
(116) |
Feb
(99) |
Mar
(181) |
Apr
(171) |
May
(112) |
Jun
(86) |
Jul
(91) |
Aug
(111) |
Sep
(77) |
Oct
(72) |
Nov
(57) |
Dec
(51) |
2007 |
Jan
(64) |
Feb
(116) |
Mar
(70) |
Apr
(74) |
May
(53) |
Jun
(40) |
Jul
(519) |
Aug
(151) |
Sep
(132) |
Oct
(74) |
Nov
(282) |
Dec
(190) |
2008 |
Jan
(141) |
Feb
(67) |
Mar
(69) |
Apr
(96) |
May
(227) |
Jun
(404) |
Jul
(399) |
Aug
(96) |
Sep
(120) |
Oct
(205) |
Nov
(126) |
Dec
(261) |
2009 |
Jan
(136) |
Feb
(136) |
Mar
(119) |
Apr
(124) |
May
(155) |
Jun
(98) |
Jul
(136) |
Aug
(292) |
Sep
(174) |
Oct
(126) |
Nov
(126) |
Dec
(79) |
2010 |
Jan
(109) |
Feb
(83) |
Mar
(139) |
Apr
(91) |
May
(79) |
Jun
(164) |
Jul
(184) |
Aug
(146) |
Sep
(163) |
Oct
(128) |
Nov
(70) |
Dec
(73) |
2011 |
Jan
(235) |
Feb
(165) |
Mar
(147) |
Apr
(86) |
May
(74) |
Jun
(118) |
Jul
(65) |
Aug
(75) |
Sep
(162) |
Oct
(94) |
Nov
(48) |
Dec
(44) |
2012 |
Jan
(49) |
Feb
(40) |
Mar
(88) |
Apr
(35) |
May
(52) |
Jun
(69) |
Jul
(90) |
Aug
(123) |
Sep
(112) |
Oct
(120) |
Nov
(105) |
Dec
(116) |
2013 |
Jan
(76) |
Feb
(26) |
Mar
(78) |
Apr
(43) |
May
(61) |
Jun
(53) |
Jul
(147) |
Aug
(85) |
Sep
(83) |
Oct
(122) |
Nov
(18) |
Dec
(27) |
2014 |
Jan
(58) |
Feb
(25) |
Mar
(49) |
Apr
(17) |
May
(29) |
Jun
(39) |
Jul
(53) |
Aug
(52) |
Sep
(35) |
Oct
(47) |
Nov
(110) |
Dec
(27) |
2015 |
Jan
(50) |
Feb
(93) |
Mar
(96) |
Apr
(30) |
May
(55) |
Jun
(83) |
Jul
(44) |
Aug
(8) |
Sep
(5) |
Oct
|
Nov
(1) |
Dec
(1) |
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
(3) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
(7) |
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
|
|
1
(9) |
2
(2) |
3
(2) |
4
(1) |
5
(14) |
6
(3) |
7
(1) |
8
(3) |
9
|
10
(7) |
11
(4) |
12
|
13
(11) |
14
(1) |
15
(2) |
16
|
17
|
18
|
19
(3) |
20
(2) |
21
|
22
|
23
(1) |
24
|
25
|
26
(1) |
27
|
28
|
29
|
|
I've been working on an application that uses matplotlib as its plotting library, and I've been noticing a steady decrease in performance over time. I figured out the cause as coming from the matplotlib SpanSelector widget - I had to create a new widget every time the axes were cleared, as the SpanSelector would not draw correctly afterwards. The event processing calls were still being made though, so over time I collected hundreds of SpanSelectors, rendering the app unusable after a while. This patch adds a new_axes method to the SpanSelector that can be called to simply re-assign the spanselector to a new axes so I only need one. Below is a diff against the latest svn. Also, is it better practice to submit patches like this to this mailing list, or the sourceforge tracker? I've seen some people do both, and it seems like the tracker isn't kept up very well... Index: lib/matplotlib/widgets.py =================================================================== --- lib/matplotlib/widgets.py (revision 4950) +++ lib/matplotlib/widgets.py (working copy) @@ -829,12 +829,9 @@ self.ax = ax self.visible = True - self.canvas = ax.figure.canvas - self.canvas.mpl_connect('motion_notify_event', self.onmove) - self.canvas.mpl_connect('button_press_event', self.press) - self.canvas.mpl_connect('button_release_event', self.release) - self.canvas.mpl_connect('draw_event', self.update_background) - + self.cids=[] + self.canvas = None + self.rect = None self.background = None @@ -847,12 +844,30 @@ # Needed when dragging out of axes self.buttonDown = False self.prev = (0, 0) + + self.new_axes(ax) + + def new_axes(self,ax): + self.ax = ax + if self.canvas is not ax.figure.canvas: + for i,cid in enumerate(self.cids[:]): + try: + self.canvas.mpl_disconnect(cid) + except: #if the old canvas is dead or anything else unexpected + pass + self.cids.remove(cid) + + self.canvas = ax.figure.canvas + self.cids.append(self.canvas.mpl_connect('motion_notify_event', self.onmove)) + self.cids.append(self.canvas.mpl_connect('button_press_event', self.press)) + self.cids.append(self.canvas.mpl_connect('button_release_event', self.release)) + self.cids.append(self.canvas.mpl_connect('draw_event', self.update_background)) if self.direction == 'horizontal': - trans = blended_transform_factory(self.ax.transData, self.ax.transAxes) + trans = blend_xy_sep_transform(self.ax.transData, self.ax.transAxes) w,h = 0,1 else: - trans = blended_transform_factory(self.ax.transAxes, self.ax.transData) + trans = blend_xy_sep_transform(self.ax.transAxes, self.ax.transData) w,h = 1,0 self.rect = Rectangle( (0,0), w, h, transform=trans,
I have been having some very strange import problems in Mayavi2. Basically the namespace packages in enthought did not import properly. I finally narrowed them down to the fact that I had installed matplotlib using setuptools, and that in the beginning of my easy_install.pth file I had /home/varoquau/dev/matplotlib/trunk/matplotlib/lib, in which there is an enthought directory. This breaks the setuptools namespace packages magic. The short term solution is to move this line at the end of the easy_install.pth. I am however worried: this is a major weakness of setuptools namespace packages, and it will happen to other people. I have no solution (sorry) but this problem needs to be addressed. Cheers, Gaël
On Sun, Feb 10, 2008 at 09:41:34AM -0600, John Hunter wrote: > It is likely we will support enthought traits for matplotlob figures > in the not too distant future -- at that point, many of the plot > elements will have UI dialogs for customization, at least for certain > backends (Qt and WX most likely) I am so happy to hear you say this. With Traits in MPL, it would be possible to build an interactive plotting application based around envisage, using other envisage plugins for a python shell and an array editor. Moreover, if the MPL plugin is well-designed, it could be used in other envisage application. There still is work to do, but I can see the pieces of the puzzle coming together. Cheers, Gaël
John Hunter wrote: > On Feb 10, 2008 7:32 AM, Neal Becker > <ndb...@gm...> wrote: >> The available plotting in pylab is good, but could be a lot better. I've >> used grace (xmgrace) for years and it's great. After bringing up the >> plot, I can interactively modify it in all kinds of ways. > > Well, you can certainly modify a matplotlib plot interactively, but > you have to use the plotting methods. Do you mean with a GUI? > Yes, I meant with a gui. Not just a minimal gui, but a full-featured one. > Chaco has very good support for using a GUI to modify plot elements, > as does veusz, though they ack some of the features matplotlib > provides. I'm curious about chaco. Looks like no egg for me. Fedora8 x86-64.
On Feb 10, 2008 7:32 AM, Neal Becker <ndb...@gm...> wrote: > The available plotting in pylab is good, but could be a lot better. I've > used grace (xmgrace) for years and it's great. After bringing up the plot, > I can interactively modify it in all kinds of ways. Well, you can certainly modify a matplotlib plot interactively, but you have to use the plotting methods. Do you mean with a GUI? Chaco has very good support for using a GUI to modify plot elements, as does veusz, though they ack some of the features matplotlib provides. It is likely we will support enthought traits for matplotlob figures in the not too distant future -- at that point, many of the plot elements will have UI dialogs for customization, at least for certain backends (Qt and WX most likely) JDH
The available plotting in pylab is good, but could be a lot better. I've used grace (xmgrace) for years and it's great. After bringing up the plot, I can interactively modify it in all kinds of ways. Any thoughts on a good package to use with pylab? (I know I can easily enough get pylab to use grace. One problem, though, is that grace is pretty old now. It is based on Motif. I'd love to see it ported to say, Qt, but I'm sure that's a huge effort)
I noticed while making some plots with upper bound error bars that whenever Axes.errorbars is called with any of the errorbars chosen as upper or lower bounds, that the color cycle was off, skipping over 2 colors each time another errorbar plot was made (e.g. the first would be green and the second would be cyan instead of blue,green,red,cyan). Looking into the axes class, it appears that if you don't specify a color and want the markers to be drawn over the errorbars, the color cycle has already been skipped over one because of calls to draw the markers into the plot. The solution is to change all the lines that say " ls='None' " in the errorbar method to instead say " ls='k' " - this will prevent those calls from cycling the colors, and hence only the call to actually draw the markers will do so. Can this patch be committed to svn?
When using unitized data any call to 'set_xlim' or 'set_ylim' will reset any user specified labels or tickers for a given axis and replace it with the values specified via the unitized data 'axisinfo' See the following for an example: ########################################### from basic_units import cm, inch from pylab import figure, show import numpy cms = cm *numpy.arange(0, 10, 2) fig = figure() ax1 = fig.add_subplot(2,2,1) ax1.plot(cms, cms) ax2 = fig.add_subplot(2,2,2) ax2.plot(cms, cms, xunits=cm, yunits=inch) ax3 = fig.add_subplot(2,2,3) ax3.plot(cms, cms, xunits=inch, yunits=cm) ax3.set_xlabel( "My Label" ) ax3.set_xlim(3, 6) # scalars are interpreted in current units # Since we call set_xlim with unitized data, the label will be reset. ax4 = fig.add_subplot(2,2,4) ax4.plot(cms, cms, xunits=inch, yunits=inch) ax4.set_xlabel( "My Label" ) ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches show() ########################################### --James Evans
On Fri, Feb 08, 2008 at 08:15:20AM +0100, Gael Varoquaux wrote: > On Thu, Feb 07, 2008 at 11:31:11AM -0500, Paul Kienzle wrote: > > There are two ways to do this in wx. > > > One is to use eventloop.Dispatch() which waits until the next available > > event: > > > [...] > > > The other is to trigger a loop.Exit() from the click callback. > > > [...] > > Very nice. I am impressed. We need to find a way of doing the same in > other toolkits. Way can however change the function call flush_event to > give it an "until" callback (and maybe rename it to > "wait_interactively"), and move the busy waiting code in the > backend-dependant part of the code. That way we can remove it backend > after backend. Having played with both "flush_until" and "start/stop" I have to say I prefer the start/stop interface. It removes the need for users to share a 'done' variable between the callback and the caller and the need to create a dummy lambda:done function. Also, it is a better match to the semantics of wx/gtk/qt (see below). I don't like the names start_event_loop/stop_event_loop, but couldn't think of anything better. How about: gui_wait/end_wait? - Paul ----- Proposed generic implementation based on flush_event and sleep, to be put into CanvasBase: def gui_wait(self, timeout=0): """Run the event loop.""" if timeout == 0: timeout = npy.inf timestep = 0.01 counter = 0 self._waiting = True while self._waiting and counter*timestep < timeout: self.flush_events() time.sleep(timestep) counter += 1 def end_wait(self): """Stop the event loop.""" self._waiting = False Suggested implementation for backend_gtk (untested!!!): def gui_wait(self, timeout=0): """Run the gtk event loop.""" # TODO: call self.end_wait() on window close self._waiting = True if timeout > 0: timer = gtk.gobject.timeout_add(timeout,self._onTimer) gtk.main() self._waiting = False gobject.source_remove(timer) def _onTimer(self): self.end_wait() return False def end_wait(self): """Stop the gtk event loop.""" if self._waiting: gtk.main_quit()
On Thu, Feb 07, 2008 at 11:31:11AM -0500, Paul Kienzle wrote: > There are two ways to do this in wx. > One is to use eventloop.Dispatch() which waits until the next available > event: > [...] > The other is to trigger a loop.Exit() from the click callback. > [...] Very nice. I am impressed. We need to find a way of doing the same in other toolkits. Way can however change the function call flush_event to give it an "until" callback (and maybe rename it to "wait_interactively"), and move the busy waiting code in the backend-dependant part of the code. That way we can remove it backend after backend. I can contribute a bit to this refactoring, but give me a couple of weeks before. Cheers, Gaël
On Wed, Feb 06, 2008 at 01:21:30AM +0100, Gael Varoquaux wrote: > On Tue, Feb 05, 2008 at 07:16:59PM -0500, Paul Kienzle wrote: > > How about giving flush_events() an until=condition and timeout=n keywords > > so that flush_events becomes: > > > if timeout > 0: set timer event which triggers out_of_time > > while get next event: > > process event > > if out_of_time or until(): break > > I'd say this is exactly the way to do it. The problem is that under GTK > is seems fairly easy to do, under Tk it seems feasible, but under Qt and > under Wx I have no clue how to do this. We can always fallback to > busy-waiting for these toolkits. There are two ways to do this in wx. One is to use eventloop.Dispatch() which waits until the next available event: def _onTimeout(self,evt): 'event loop timer completed' self._event_loop_running = False def event_loop(self, done=lambda:False, timeout=0): 'run the event loop until done or timeout' timer = wx.Timer(self) self._event_loop_running = True if timeout > 0: timer.Start(timeout*1000, oneShot=True) self.Bind(wx.EVT_TIMER, self._onTimeout, timer) loop = wx.EventLoop() while self._event_loop_running and loop.Dispatch() and not done(): #print "Processing event" pass self._event_loop_running = False timer.Stop() The other is to trigger a loop.Exit() from the click callback. Rather than passing a stop condition to the event_loop method, the user would call start_event_loop to start collecting events, and stop_event_loop in the event callback when the terminating condition is reached. In the ginput example, this is just calling self.fig.canvas.stop_event_loop() rather than self.done = True in the callback. The code for this is: def __init__ ... self._event_loop = wx.EventLoop() ... def start_event_loop(self, timeout=0): timer = wx.Timer(self) if timeout > 0: timer.Start(timeout*1000, oneShot=True) self.Bind(wx.EVT_TIMER, self.stop_event_loop, timer) self._event_loop.Run() timer.Stop() def stop_event_loop(self, event=None): if self._event_loop.IsRunning(): self._event_loop.Exit() Note that we need to also check for the window closing while the event loop is running, which we can do using the following at the beginning of start_event_loop: root = self.GetTopLevelParent() root.Bind(wx.EVT_CLOSE, self.stop_event_loop) This will unfortunately kill any window kill event that the application defined. We may also want to give the application direct access to the timer for the purpose of creating animations independent of the toolkit. - Paul
On Wed, Feb 06, 2008 at 01:21:30AM +0100, Gael Varoquaux wrote: > On Tue, Feb 05, 2008 at 07:16:59PM -0500, Paul Kienzle wrote: > > I'll look around some more and see if I can find the sleep until next > > event function in wx. > > Yeah, sleep, I need more of that. Or maybe you can find wx.coffee ? Sleep not found, despite half the night trying. What follows three experiments I tried, but now I'm out of ideas. The last thing to do would be to follow your suggestion and move the busy loop from ginput to CanvasBase and let the individual backends override with a better solution if available. - Paul Attempted solutions for modal wx event processing: 1. Run a private event loop with a timer every 0.1s to see if the user has done selecting. This works, but it doesn't like it if the window is closed before completion. I didn't test for it, but super-fast clicking should let the user sometimes select an extra point, so not a great solution. def event_loop(self, done=lambda:False, timeout=0): 'run the eventloop until done or timeout' print "Running private event loop" loop = wx.EventLoop() # stop after timeout period def donewaiting(*args,**kw): print "Done waiting" loop.Exit() if timeout > 0: print "Starting timer" outtimer = wx.Timer(self, id=MODAL_TIMEOUT_TIMER) outtimer.Start(timeout*1000, oneShot=True) self.Bind(wx.EVT_TIMER, donewaiting, outtimer) # check if done every 0.1 s def checkdone(*args,**kw): if done(): loop.Exit() steptimer = wx.Timer(self, id=MODAL_STEP_TIMER) steptimer.Start(100, oneShot=False) self.Bind(wx.EVT_TIMER, checkdone, steptimer) loop.Run() steptimer.Stop() return 2. What seems like it should work is to use an event handler which checks after processing each event whether or not this completes the condition and so we can exit the loop. However, ProcessEvent never seems to be called. Reading elsewhere I see that ProcessEvent is not a virtual function in wx, so presumably we can't override it in a subclass of wx.EvtHandler. # Redirect input events to new handler class ModalHandler(wx.EvtHandler): def ProcessEvent(self, evt): print "Processing event" if done(): loop.Exit() return False # True if processed print "Pushing handler" handler = ModalHandler() self.PushEventHandler(handler) print "enabled",handler.GetEvtHandlerEnabled() print "handler->next",handler.GetNextHandler() print "self->previous",self.GetPreviousHandler() loop.Run() self.PopEventHandler(False) print "Done!" 3. Revising two somewhat, I send all events for the canvas through my own event handler. To make sure I see each one I bind each window event to my own dispatcher as well as to the underlying window. I then use this handler rather than self in the canvas __init__. This fails because either the window handler is not called or it is called twice, depending on whether PushEventHandler and ProcessEvent are called. It also fails if the window is closed unexpectedly. class ModalHandler(wx.EvtHandler): def __init__(self, window): print "Creating handler" wx.EvtHandler.__init__(self) self.done = lambda:False window.PushEventHandler(self) self.window = window self.timer = wx.Timer() self.Bind(wx.EVT_TIMER, self.OnTimeout, self.timer) self.loop = wx.EventLoop() def _dispatch(self, evt): """Ick! ProcessEvent is not virtual, so we can't override directly!""" #print "Processing event" self.window.ProcessEvent(evt) if self.done(): self.loop.Exit() print "Returning event" return True def EndModal(self): """Force the loop to exit""" self.done = lambda:True def Bind(self,evt,action,*args,**kw): # Force all events through ProcessEvent. This is the first binding. # ProcessEvent will dispatch the event to the window itself, so be # sure to tell the window what to do with the event. This is the # second binding. if wx.VERSION_STRING >= '2.5': # Event handlers 2.5 print "Binding 2.5" wx.EvtHandler.Bind(self.window,evt,action,*args,**kw) wx.EvtHandler.Bind(self,evt,self._dispatch) else: print "Binding 2.4" evt(self,self.ProcessEvent) evt(self.window,*args,**kw) def OnTimeout(self): print "timeout" self.loop.Exit() def RunLoop(self, done=lambda:False, timeout=0): print "Running loop" self.done = done if timeout > 0: self.timer.Start(timeout, oneShot=True) try: self.loop.Run() finally: self.timer.Stop() self.done = lambda:False
On Tue, Feb 05, 2008 at 07:16:59PM -0500, Paul Kienzle wrote: > How about giving flush_events() an until=condition and timeout=n keywords > so that flush_events becomes: > if timeout > 0: set timer event which triggers out_of_time > while get next event: > process event > if out_of_time or until(): break I'd say this is exactly the way to do it. The problem is that under GTK is seems fairly easy to do, under Tk it seems feasible, but under Qt and under Wx I have no clue how to do this. We can always fallback to busy-waiting for these toolkits. This indeed seems to be the way to go. Maybe I would empty the event stack when the "until()" condition is met, before returning to the caller, and thus blocking again. > I'll look around some more and see if I can find the sleep until next > event function in wx. Yeah, sleep, I need more of that. Or maybe you can find wx.coffee ? Cheers, Gaël
On Wed, Feb 06, 2008 at 12:38:32AM +0100, Gael Varoquaux wrote: > On Tue, Feb 05, 2008 at 06:30:53PM -0500, Paul Kienzle wrote: > > Setting the timeout to 0.01s for the busy loop in ginput seems excessive. > > Since it is waiting for human interaction, generally 0.1 seconds is good > > enough. > > I had gone for that originally, but it looked quite ugly when moving the > window around. This busy waiting is quite ugly, but I have found a way of > avoid it. IMHO it should be done in the toolkit's event loop, but it > seems that trying to do it this would add gobbles of code for little > gain. How about giving flush_events() an until=condition and timeout=n keywords so that flush_events becomes: if timeout > 0: set timer event which triggers out_of_time while get next event: process event if out_of_time or until(): break Looking through wx I don't see how to "get next event", my choices being run all events (MainLoop) or run pending events. I do see an "exit main loop" function, so for wx at least one could redirect the event handler for the window and run all the events, exiting the main loop when done, but that seems ugly. I'll look around some more and see if I can find the sleep until next event function in wx. - Paul
On Tue, Feb 05, 2008 at 06:46:19PM -0500, Paul Kienzle wrote: > In my applications I select multiple points from a particular line, > highlighting the point that will be selected as the mouse cursor moves. > I put a text message on the plot explaining what to do which disappears > when the selection is complete. The idea of the text message is pretty cool in term of usability. All in all the features that you describe are relly nice. I am sure that if you find a way to make them toolkit-agnostic they would be a great addition to MPL. > Some other useful cases are selecting an x-range, a y-range or a box, > with the appropriate shading for the selected region. Same thing here, this is quite nice too. I think this behavior can now be created using ginput, but it would be cool to have it out of the box. Sorry, I can't work on it know. Gaël
On Tue, Feb 05, 2008 at 11:23:14PM +0100, Gael Varoquaux wrote: > On Tue, Feb 05, 2008 at 04:11:59PM -0600, John Hunter wrote: > > Also, my version of GaelInput has seemed to stop evolving. This > > version has the option to draw lines between clicks, which I use a > > lot. Also, the default timeout is 0 now, since you can always > > right-click to abort. > > You can still use this behavoir, using a timeout of zero, n = 0, and the > middle click to end (I use right_click to cancel points). I am not sure > what the default timeout should be. If you have strong opinions about it > being 0, that's fine with me. > > As far as n = 0 being the default, I think this is a bad idea. First of > all, it break matlab-compatibility for no good reasons, second in most > cases, IMHO, the naive programmer only wants one point, and puts some > logics afterwards. He will not read the doc, and wont understand why his > function is not returning after one click (so many people don't even know > how to read docstring, I am not kidding). > > As for the lines, having lines implies that there is a connection order > in your points, which is not always the case. I suggest thus adding a > optional (oof by default) keyword argument for this behavior. In my applications I select multiple points from a particular line, highlighting the point that will be selected as the mouse cursor moves. I put a text message on the plot explaining what to do which disappears when the selection is complete. Some other useful cases are selecting an x-range, a y-range or a box, with the appropriate shading for the selected region. This is still in Tcl/Tk+BLT; I haven't moved it over to Python yet. - Paul
On Tue, Feb 05, 2008 at 06:30:53PM -0500, Paul Kienzle wrote: > This failed for me in wx. > I posted a patch r4943 which moves flush_events from Figure to Canvas, > and removes the Yield in gui_repaint which caused an exception in wx. > The showfig callback in FigureManagerWx had an unreferenced global > variable figwin which I removed. It wasn't obvious to me why this > was broken, or how long it has been broken, but the ginput example > works for me now. Yes, I had noticed this problem (did I signal it to the list, or did I forget ?) I wasn't too sure what to do about it, as I don't really know the MPL codebase. As a result I tested the principle under Wx in an older version of MPL, which did not have this problem, but also did not have Yield in gui_repaint. But you sorted out this problem, thanks a lot! > Setting the timeout to 0.01s for the busy loop in ginput seems excessive. > Since it is waiting for human interaction, generally 0.1 seconds is good > enough. I had gone for that originally, but it looked quite ugly when moving the window around. This busy waiting is quite ugly, but I have found a way of avoid it. IMHO it should be done in the toolkit's event loop, but it seems that trying to do it this would add gobbles of code for little gain. Cheers, Gaël
On Tue, Feb 05, 2008 at 01:05:55PM -1000, Eric Firing wrote: > Paul Kienzle wrote: > > Hi, > > > > I have a patch to post the results of examples/backend_driver.py to > > a backend specific directory, after first clearing the directory. > > Excellent idea. > > > > > Shall I commit? > > Yes. Done. - Paul
On Tue, Feb 05, 2008 at 03:58:08PM -0600, John Hunter wrote: > On Feb 2, 2008 8:48 AM, Gael Varoquaux <gae...@no...> wrote: > > > Here is the new patch. I added visual feedback when accumulating points. > > I hope the docstrings are clear. > > Great -- thanks again. I applied this patch and created a new example > ginput_demo.py > > Tested on GTKAgg and TkAgg on my system, and looks good so far. This failed for me in wx. I posted a patch r4943 which moves flush_events from Figure to Canvas, and removes the Yield in gui_repaint which caused an exception in wx. The showfig callback in FigureManagerWx had an unreferenced global variable figwin which I removed. It wasn't obvious to me why this was broken, or how long it has been broken, but the ginput example works for me now. Setting the timeout to 0.01s for the busy loop in ginput seems excessive. Since it is waiting for human interaction, generally 0.1 seconds is good enough. - Paul
Paul Kienzle wrote: > Hi, > > I have a patch to post the results of examples/backend_driver.py to > a backend specific directory, after first clearing the directory. Excellent idea. > > Shall I commit? Yes. Eric > > - Paul > > Index: backend_driver.py > =================================================================== > --- backend_driver.py (revision 4942) > +++ backend_driver.py (working copy) > @@ -131,6 +131,16 @@ > _backend = 'cairo' > else: > _backend = backend > + > + # Clear the destination directory for the examples > + path = backend > + if os.path.exists(path): > + import glob > + for fname in os.listdir(path): > + os.unlink(os.path.join(path,fname)) > + else: > + os.mkdir(backend) > + > for fname in files: > if fname in exclude: > print '\tSkipping %s, known to fail on backend: %s'%backend > @@ -138,7 +148,7 @@ > > print ('\tdriving %-40s' % (fname)), > basename, ext = os.path.splitext(fname) > - outfile = basename + '_%s'%backend > + outfile = os.path.join(path,basename) > tmpfile_name = '_tmp_%s.py' % basename > tmpfile = file(tmpfile_name, 'w') > > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Matplotlib-devel mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
Hi, I have a patch to post the results of examples/backend_driver.py to a backend specific directory, after first clearing the directory. Shall I commit? - Paul Index: backend_driver.py =================================================================== --- backend_driver.py (revision 4942) +++ backend_driver.py (working copy) @@ -131,6 +131,16 @@ _backend = 'cairo' else: _backend = backend + + # Clear the destination directory for the examples + path = backend + if os.path.exists(path): + import glob + for fname in os.listdir(path): + os.unlink(os.path.join(path,fname)) + else: + os.mkdir(backend) + for fname in files: if fname in exclude: print '\tSkipping %s, known to fail on backend: %s'%backend @@ -138,7 +148,7 @@ print ('\tdriving %-40s' % (fname)), basename, ext = os.path.splitext(fname) - outfile = basename + '_%s'%backend + outfile = os.path.join(path,basename) tmpfile_name = '_tmp_%s.py' % basename tmpfile = file(tmpfile_name, 'w')
On Tue, Feb 05, 2008 at 04:11:59PM -0600, John Hunter wrote: > Also, my version of GaelInput has seemed to stop evolving. This > version has the option to draw lines between clicks, which I use a > lot. Also, the default timeout is 0 now, since you can always > right-click to abort. You can still use this behavoir, using a timeout of zero, n = 0, and the middle click to end (I use right_click to cancel points). I am not sure what the default timeout should be. If you have strong opinions about it being 0, that's fine with me. As far as n = 0 being the default, I think this is a bad idea. First of all, it break matlab-compatibility for no good reasons, second in most cases, IMHO, the naive programmer only wants one point, and puts some logics afterwards. He will not read the doc, and wont understand why his function is not returning after one click (so many people don't even know how to read docstring, I am not kidding). As for the lines, having lines implies that there is a connection order in your points, which is not always the case. I suggest thus adding a optional (oof by default) keyword argument for this behavior. I am working late hours currently to try to improve the mayavi2 docs before we do a major release, I can't work on this patchs. Jack, do you feel like writing it. It should be pretty trivial by simply extending what I wrote for displaying points, and cleaning them afterward, which is the hardest part. Sorry not to propose to do it myself, but I already put myself behind the release schedule by hacking on this on saturday, and I am not even talking about my day work. Cheers, Gaël
I'm not at all attached to any particular functionality. Feel free to mangle it as you see fit! On Feb 5, 2008 5:11 PM, John Hunter <jd...@gm...> wrote: > On Feb 5, 2008 3:58 PM, John Hunter <jd...@gm...> wrote: > > On Feb 2, 2008 8:48 AM, Gael Varoquaux <gae...@no...> wrote: > > > > > Here is the new patch. I added visual feedback when accumulating points. > > > I hope the docstrings are clear. > > > > Great -- thanks again. I applied this patch and created a new example > > ginput_demo.py > > Jack replied to me offlist so I am going to paste in his post below. > Perhaps you and Gael can consult on the ideal functionality of ginput > vis-a-vis optional line segment drawing, etc... > > > > From Jack Sankey <jac...@gm...> > to John Hunter <jd...@gm...>, > date Feb 5, 2008 4:02 PM > subject Re: [matplotlib-devel] ginput: blocking call for mouse input > mailed-by gmail.com > > > > > Woa, it's working on GTKAgg using wx.Yield()? You must have added some voodoo :) > > Also, my version of GaelInput has seemed to stop evolving. This > version has the option to draw lines between clicks, which I use a > lot. Also, the default timeout is 0 now, since you can always > right-click to abort. > > -Jack > > > > class GaelInput(object): > """ > Class that create a callable object to retrieve mouse click in a > blocking way, a la MatLab. Based on Gael Varoquaux's almost-working > object. Thanks Gael! I've wanted to get this working for years! > > -Jack > """ > > debug = False > cid = None # event connection object > clicks = [] # list of click coordinates > n = 1 # number of clicks we're waiting for > lines = False # if we should draw the lines > > def on_click(self, event): > """ > Event handler that will be passed to the current figure to > retrieve clicks. > """ > > # write the debug information if we're supposed to > if self.debug: print "button "+str(event.button)+": > "+str(event.xdata)+", "+str(event.ydata) > > # if this event's a right click we're done > if event.button == 3: > self.done = True > return > > # if it's a valid click (and this isn't an extra event > # in the queue), append the coordinates to the list > if event.inaxes and not self.done: > self.clicks.append([event.xdata, event.ydata]) > > # now if we're supposed to draw lines, do so > if self.lines and len(self.clicks) > 1: > event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]], > [self.clicks[-1][1], self.clicks[-2][1]], > color='w', linewidth=2.0, > scalex=False, scaley=False) > event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]], > [self.clicks[-1][1], self.clicks[-2][1]], > color='k', linewidth=1.0, > scalex=False, scaley=False) > _pylab.draw() > > # if we have n data points, we're done > if len(self.clicks) >= self.n and self.n is not 0: > self.done = True > return > > > def __call__(self, n=1, timeout=0, debug=False, lines=False): > """ > Blocking call to retrieve n coordinate pairs through mouse clicks. > > n=1 number of clicks to collect. Set n=0 to keep collecting > points until you click with the right mouse button. > > timeout=30 maximum number of seconds to wait for clicks > before giving up. > timeout=0 to disable > > debug=False show each click event coordinates > > lines=False draw lines between clicks > """ > > # just for printing the coordinates > self.debug = debug > > # for drawing lines > self.lines = lines > > # connect the click events to the on_click function call > self.cid = _pylab.connect('button_press_event', self.on_click) > > # initialize the list of click coordinates > self.clicks = [] > > # wait for n clicks > self.n = n > self.done = False > t = 0.0 > while not self.done: > # key step: yield the processor to other threads > _wx.Yield(); > _time.sleep(0.1) > > # check for a timeout > t += 0.1 > if timeout and t > timeout: print "ginput timeout"; break; > > # All done! Disconnect the event and return what we have > _pylab.disconnect(self.cid) > self.cid = None > return _numpy.array(self.clicks) > > > > def ginput(n=1, timeout=0, show=True, lines=False): > """ > Simple functional call for physicists. This will wait for n clicks > from the user and > return a list of the coordinates of each click. > > n=1 number of clicks to collect > timeout=30 maximum number of seconds to wait for clicks > before giving up. > timeout=0 to disable > show=True print the clicks as they are received > lines=False draw lines between clicks > """ > > x = GaelInput() > return x(n, timeout, show, lines) >
On Feb 5, 2008 3:58 PM, John Hunter <jd...@gm...> wrote: > On Feb 2, 2008 8:48 AM, Gael Varoquaux <gae...@no...> wrote: > > > Here is the new patch. I added visual feedback when accumulating points. > > I hope the docstrings are clear. > > Great -- thanks again. I applied this patch and created a new example > ginput_demo.py Jack replied to me offlist so I am going to paste in his post below. Perhaps you and Gael can consult on the ideal functionality of ginput vis-a-vis optional line segment drawing, etc... From Jack Sankey <jac...@gm...> to John Hunter <jd...@gm...>, date Feb 5, 2008 4:02 PM subject Re: [matplotlib-devel] ginput: blocking call for mouse input mailed-by gmail.com Woa, it's working on GTKAgg using wx.Yield()? You must have added some voodoo :) Also, my version of GaelInput has seemed to stop evolving. This version has the option to draw lines between clicks, which I use a lot. Also, the default timeout is 0 now, since you can always right-click to abort. -Jack class GaelInput(object): """ Class that create a callable object to retrieve mouse click in a blocking way, a la MatLab. Based on Gael Varoquaux's almost-working object. Thanks Gael! I've wanted to get this working for years! -Jack """ debug = False cid = None # event connection object clicks = [] # list of click coordinates n = 1 # number of clicks we're waiting for lines = False # if we should draw the lines def on_click(self, event): """ Event handler that will be passed to the current figure to retrieve clicks. """ # write the debug information if we're supposed to if self.debug: print "button "+str(event.button)+": "+str(event.xdata)+", "+str(event.ydata) # if this event's a right click we're done if event.button == 3: self.done = True return # if it's a valid click (and this isn't an extra event # in the queue), append the coordinates to the list if event.inaxes and not self.done: self.clicks.append([event.xdata, event.ydata]) # now if we're supposed to draw lines, do so if self.lines and len(self.clicks) > 1: event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]], [self.clicks[-1][1], self.clicks[-2][1]], color='w', linewidth=2.0, scalex=False, scaley=False) event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]], [self.clicks[-1][1], self.clicks[-2][1]], color='k', linewidth=1.0, scalex=False, scaley=False) _pylab.draw() # if we have n data points, we're done if len(self.clicks) >= self.n and self.n is not 0: self.done = True return def __call__(self, n=1, timeout=0, debug=False, lines=False): """ Blocking call to retrieve n coordinate pairs through mouse clicks. n=1 number of clicks to collect. Set n=0 to keep collecting points until you click with the right mouse button. timeout=30 maximum number of seconds to wait for clicks before giving up. timeout=0 to disable debug=False show each click event coordinates lines=False draw lines between clicks """ # just for printing the coordinates self.debug = debug # for drawing lines self.lines = lines # connect the click events to the on_click function call self.cid = _pylab.connect('button_press_event', self.on_click) # initialize the list of click coordinates self.clicks = [] # wait for n clicks self.n = n self.done = False t = 0.0 while not self.done: # key step: yield the processor to other threads _wx.Yield(); _time.sleep(0.1) # check for a timeout t += 0.1 if timeout and t > timeout: print "ginput timeout"; break; # All done! Disconnect the event and return what we have _pylab.disconnect(self.cid) self.cid = None return _numpy.array(self.clicks) def ginput(n=1, timeout=0, show=True, lines=False): """ Simple functional call for physicists. This will wait for n clicks from the user and return a list of the coordinates of each click. n=1 number of clicks to collect timeout=30 maximum number of seconds to wait for clicks before giving up. timeout=0 to disable show=True print the clicks as they are received lines=False draw lines between clicks """ x = GaelInput() return x(n, timeout, show, lines)
On Feb 2, 2008 8:48 AM, Gael Varoquaux <gae...@no...> wrote: > Here is the new patch. I added visual feedback when accumulating points. > I hope the docstrings are clear. Great -- thanks again. I applied this patch and created a new example ginput_demo.py Tested on GTKAgg and TkAgg on my system, and looks good so far. JDH