From: Arnd B. <arn...@we...> - 2004-07-19 07:33:31
|
Hi, I am following this mailing list for a while now and considering to convert to matplotlib at some point. Whether this is feasable depends on the following two points: 1) I would like to know if there is an equivalent to the scipy.xplt.mouse command which (in its simplest form) waits for a mouse click and returns its coordinates: Example: #------------------------------------- from scipy.xplt import * x=arange(0.0,1.0,0.1) plg(x*x,x) m=mouse(1,-1,"click with the mouse") print "x,y=",m[0],m[1] #------------------------------------- John's reply http://mail.python.org/pipermail/python-list/2004-April/216550.html shows that it is possible to connect mouse events with functions. However, that code depends on the back-end and is not as short as the above one (though more flexible, of course ;-). 2) For one set of applications I would like to be able to plot several times 1000 points (or more). Optimally would be to plot one point after another to get a dynamical impression. In the application I have in mind there would be no need to store these points (ie zooming is not necessary) which normally degrades performance. Presently for me the solution for this type of things is our PlottingCanvas for wxPython, see http://www.physik.tu-dresden.de/~baecker/python/plot.html and there the StandardMap.py example. (this is not to advertise this, but just that you get an idea of what I have in mind. In the code there are couple of tricks to speed things up). In the end I would be happy to dump our PlottingCanvas in favour of matplotlib! Best, Arnd |
From: John H. <jdh...@ac...> - 2004-07-19 17:48:24
|
>>>>> "Arnd" == Arnd Baecker <arn...@we...> writes: Arnd> Hi, I am following this mailing list for a while now and Arnd> considering to convert to matplotlib at some point. Whether Arnd> this is feasable depends on the following two points: Arnd> 1) I would like to know if there is an equivalent to the Arnd> scipy.xplt.mouse command which (in its simplest form) waits Arnd> for a mouse click and returns its coordinates: Arnd> Example: #------------------------------------- from Arnd> scipy.xplt import * x=arange(0.0,1.0,0.1) plg(x*x,x) Arnd> m=mouse(1,-1,"click with the mouse") print "x,y=",m[0],m[1] Arnd> #------------------------------------- Arnd> John's reply Arnd> http://mail.python.org/pipermail/python-list/2004-April/216550.html Arnd> shows that it is possible to connect mouse events with Arnd> functions. However, that code depends on the back-end and Arnd> is not as short as the above one (though more flexible, of Arnd> course ;-). For some time, we've provided basic cross GUI event handling with the canvas.connect method. Todd Miller had the idea to port the gtk connect interface to Tk. For example, the demo coords_demo.py runs unchanged on TkAgg and GTKAgg. This is only a partial implementation, and in CVS I've extended it a bit more. The new method is called mpl_connect, and you will be able to do, across GUIs, calls like def on_move(event): # get the x and y coords x, y = event.x, event.y ...snip... canvas.mpl_connect('motion_notify_event', on_move) I plan to provide the motion notify, on click, and key press events, and provide some extra positional information in the events, namely canvas coordinate location and axes coordinate location. The backend will handle things like flipy so the script can ignore it. I'm in the process of designing a better toolbar and am using this cross-GUI event handling to minimize the burden of implementing the toolbar in the various backends. In order to do something like the m = mouse(1,-1,"click with the mouse") print "x,y=",m[0],m[1] example, it would be necessary to implement some cross gui blocking capability, so that the execution of the script is halted until the block is removed. I don't see this as a major problem, but will require some input from people with experience on the not-GTK GUIs. It's probably not be necessary, though, since it's only a few more keystrokes to do def on_click(event): print 'x, y =', event.x, event.y canvas.mpl_connect(''button_press_event', on_click) This should be ready by the 0.61 release. BTW, as a wx expert, perhaps you have a code snippet I can use which calls the event Connect and Disconnect methods directly. I'm currently trying to figure this out for the wx implementation of mpl_connect and mpl_disconnect. Arnd> 2) For one set of applications I would like to be able to Arnd> plot several times 1000 points (or more). Optimally would Arnd> be to plot one point after another to get a dynamical Arnd> impression. In the application I have in mind there would Arnd> be no need to store these points (ie zooming is not Arnd> necessary) which normally degrades performance. Presently Arnd> for me the solution for this type of things is our Arnd> PlottingCanvas for wxPython, see Arnd> http://www.physik.tu-dresden.de/~baecker/python/plot.html Arnd> and there the StandardMap.py example. There is a lot of interest in making dynamical plotting more efficient. Currently, the entire figure is redrawn with each frame update, which is clearly not ideal for dynamic figures in which only a portion needs to be redrawn. I'm interested in making some changes to better support "real time" data acquisition, where the quotes mean "fast enough to handle most use cases". My current thought is to support drawing to subsections of the agg canvas, eg, so that a single axes, line or patch could be updated without updating the entire figure canvas. To support this, each object would need to know it's rectangular extent (done), take a snapshot of the background canvas before drawing (to be done) and know how to render itself to canvas (done). In addition, agg and the backends would need to be extended to allow drawing of subregions of the canvas, which should be fairly easy. By calling the right combination of store_background, draw and erase, you could get much faster dynamic plots. The current implementation (redrawing the entire figure) is pretty fast on a fast machine, but needs to be faster. How do you do this in PlottingCanvas? Do simply add objects to the canvas and redraw the entire canvas if you need to remove an object, or do you support selective erasing and removal of objects? JDH |
From: Arnd B. <arn...@we...> - 2004-07-20 11:03:39
|
On Mon, 19 Jul 2004, John Hunter wrote: > >>>>> "Arnd" == Arnd Baecker <arn...@we...> writes: [...] > Arnd> 1) I would like to know if there is an equivalent to the > Arnd> scipy.xplt.mouse command which (in its simplest form) waits > Arnd> for a mouse click and returns its coordinates: > > Arnd> Example: #------------------------------------- from > Arnd> scipy.xplt import * x=arange(0.0,1.0,0.1) plg(x*x,x) > Arnd> m=mouse(1,-1,"click with the mouse") print "x,y=",m[0],m[1] > Arnd> #------------------------------------- [...] > > For some time, we've provided basic cross GUI event handling with the > canvas.connect method. Todd Miller had the idea to port the gtk > connect interface to Tk. For example, the demo coords_demo.py runs > unchanged on TkAgg and GTKAgg. This is only a partial implementation, > and in CVS I've extended it a bit more. The new method is called > mpl_connect, and you will be able to do, across GUIs, calls like > > def on_move(event): > # get the x and y coords > x, y = event.x, event.y > ...snip... > > canvas.mpl_connect('motion_notify_event', on_move) > > > I plan to provide the motion notify, on click, and key press events, > and provide some extra positional information in the events, namely > canvas coordinate location and axes coordinate location. The backend > will handle things like flipy so the script can ignore it. I'm in the > process of designing a better toolbar and am using this cross-GUI > event handling to minimize the burden of implementing the toolbar in > the various backends. > > In order to do something like the > > m = mouse(1,-1,"click with the mouse") > print "x,y=",m[0],m[1] > > example, it would be necessary to implement some cross gui blocking > capability, so that the execution of the script is halted until the > block is removed. I don't see this as a major problem, but will > require some input from people with experience on the not-GTK GUIs. > It's probably not be necessary, though, since it's only a few more > keystrokes to do > > def on_click(event): print 'x, y =', event.x, event.y > canvas.mpl_connect(''button_press_event', on_click) > > This should be ready by the 0.61 release. Excellent - that sounds really good! Still I think that maybe the variant with blocking is useful as well: I am having our students in mind which were quite happy and sucessfull with scipy.xplt (in particular also those who had no previous programming experience.) Introducing them to event driven ``design'' already in the second excercise might be burdoning them too much (but maybe I am wrong). > BTW, as a wx expert, > perhaps you have a code snippet I can use which calls the event > Connect and Disconnect methods directly. I'm currently trying to > figure this out for the wx implementation of mpl_connect and > mpl_disconnect. I am definitively no wx expert - a lot of the stuff I learned from looking at Chris Barker's and Gordon Williams' code and the wxPython demo. So I also don't have an example here. (It only rings a bell that Chris maybe had some discussion on this on the wxPython mailing list - I think it was about creating custom events - maybe there is an example in Chris' FloatCanvas? Ok, I just had a _quick_ look and at the beginning of FloatCanvas.py ( http://home.comcast.net/~chrishbarker/FloatCanvas/ ) there are a couple of window.Connect. Maybe this helps... Anyway, if you did not succeed by Friday let me know and I will try to have a look over the week-end. > Arnd> 2) For one set of applications I would like to be able to > Arnd> plot several times 1000 points (or more). Optimally would > Arnd> be to plot one point after another to get a dynamical > Arnd> impression. In the application I have in mind there would > Arnd> be no need to store these points (ie zooming is not > Arnd> necessary) which normally degrades performance. Presently > Arnd> for me the solution for this type of things is our > Arnd> PlottingCanvas for wxPython, see > Arnd> http://www.physik.tu-dresden.de/~baecker/python/plot.html > Arnd> and there the StandardMap.py example. > > There is a lot of interest in making dynamical plotting more > efficient. Currently, the entire figure is redrawn with each frame > update, which is clearly not ideal for dynamic figures in which only a > portion needs to be redrawn. I'm interested in making some changes to > better support "real time" data acquisition, where the quotes mean > "fast enough to handle most use cases". Personally I am a bit sceptic, if it is possible to cater for all needs (super-fast vs. zooming/redraw of stored data, ...), sureley not at the same time but maybe a reasonable comprise is possible ;-). > My current thought is to support drawing to subsections of the agg > canvas, eg, so that a single axes, line or patch could be updated > without updating the entire figure canvas. To support this, each > object would need to know it's rectangular extent (done), take a > snapshot of the background canvas before drawing (to be done) and know > how to render itself to canvas (done). In addition, agg and the > backends would need to be extended to allow drawing of subregions of > the canvas, which should be fairly easy. By calling the right > combination of store_background, draw and erase, you could get much > faster dynamic plots. Thinking of the example I have in mind, where not untypically up to 100 x 10000 points are plotted (or even more) storing each point as an object + further information might (presumably will) slow things down and cause memory problems (that's what occurred for me with Tkinter). Anyway, in September we have a student who will set up a couple of examples and then we will see if things are fast enough (for us ;-)... > The current implementation (redrawing the entire figure) is pretty > fast on a fast machine, but needs to be faster. > > How do you do this in PlottingCanvas? Do simply add objects to the > canvas Yes (with the usual double-buffering) so for example for a circle we just call self.ScreenDC.DrawCircle(x, y, pointsize) self.BufferDC.DrawCircle(x, y, pointsize) and the border color and fill color of the circle are initialized before and only once for a sequence of successive points. Also (in the case of wx) it helps a lot if the drawing context (DC) is only initialized once for a sequence of successive points. Nikolai (Hlubek) measured the speed increase to be factor 2 for wx.wxClientDC(self) factor 10 for wx.wxBufferedDC(wx.wxClientDC(self), self._Buffer) > and redraw the entire canvas if you need to remove an object, Well, in the fastest mode of operation we don't allow for removal of objects/resizing the canvas and things like that... > or do you support selective erasing and removal of objects? No. What the PlottingCanvas does provide though is the possibility to ``move'' an object over a ``background'' plot - see AnnularBilliard.py where a ball is moving inside a two-dimensional billiard (click in the right window to specify the initial condition and move the slider upwards to increas the speed of the ball a bit). In another mode of operation we enable storing of all data points (with the corresponding speed penalty). This then allows to zoom in and redraw those data. Despite some optimizations, plotting with wx is still not as fast as for example with pgplot (wherever the bottlenecks are ;-). Best, Arnd |