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
|
|
From: Sigve T. <si...@tj...> - 2005-01-31 19:39:19
|
Steve Chaplin skrev:
>Well done. I tried it out on Linux (Fedora 3) and it works reasonably
>well.
>
>
>
Thats nice.
>I noticed a few things:
>It puts the toolbar at the top rather than the bottom of the window.
>
>
Fix by changing in NavigationToolbar2QtAgg.__init:
qt.QToolBar.__init__(self, qt.QString(""), window, qt.Qt.DockTop)
to
qt.QToolBar.__init__(self, qt.QString(""), window, qt.Qt.DockBottom)
>The graph is smaller and the colours are different than that produced
>with GTKAgg, which is strange since they both use Agg rendering.
>
>
Colors are fixed in CVS, i think.
>I think it would be better to have a 'backend_qt.py' file used as a base
>class (with a FigureCanvasQtAgg.draw() method that raises
>NotImplementedError), and with backend_qtagg.py overriding just those
>functions/methods which are specific to drawing using Agg. This would
>allow backend_qt.py code to be used to produce a QtCairo backend at a
>later date.
>
>
>
I agree, but have not time to do it right now.
Regards,
Sigve
|
|
From: John H. <jdh...@ac...> - 2005-01-31 19:37:56
|
>>>>> "Sigve" == Sigve Tjora <si...@tj...> writes:
Sigve> That probably leaves us with the OSX problems, though. Ahh,
Sigve> fixed in CVS, ok then.
I'm lost here -- as far as I know the endianess problem *was not*
fixed in CVS. I did add an agg method tostring_bgra to CVS which
appears to fix the reversed color problem. I haven't had a chance to
test this on OSX since my powerbook is at home...
Sigve> I think that QPixmap or better yet QCanvas would be the
Sigve> appropriate if you are making a pure Qt-backend, but that
Sigve> QImage is the choice for a backend with other rendering as
Sigve> Agg or Cairo.
OK, I'll leave that to you, since I now next to nothing about qt.
Sigve> Adding this to the end of FigureCanvasQtAgg.__init__ will
Sigve> fix tracking:
Sigve> self.setMouseTracking(True)
Yep, works. Easy enough.
Any thoughts about why the figure doesn't refresh during pan and zoom.
On my box (linux) the update only occurs after the mouse button is
released.
The other annoyance vis-a-vis nav toolbar I notice is the flicker when
doing the rubberbanding for zoom to rect. Any idea how to implement
double buffering to avoid the flicker?
Thanks!
JDH
|
|
From: Sigve T. <si...@tj...> - 2005-01-31 19:24:42
|
John Hunter wrote:
> John> * The only explanation I can think of for why the colors
> John> are wrong is that qt has a different byte order for images
> John> than you are getting from agg (is could it be bgra instead
> John> of rgba, or that something is wrong with the endianess...)
> John> If you need a different byte ordering /pixel format, I can
> John> provide the required method in the agg backend. I note that
> John> the saved figures *do* have the right color scheme, which
> John> supports this idea.
>
>Another clue that endianess is playing a role here is that the colors
>are dramatically different on OSX (which I tested yesterday) ans linux
>which I tested today. But I think it's more than an endian problem,
>because the colors are wrong on both platforms. On linux, it looks
>like the endianess is right, but it's an rgb versus bgr thing, since
>the colors are backwards on
>
> from pylab import *
> subplot(211)
> plot([1,2,3], color='red')
>
> subplot(212)
> plot([1,2,3], color='blue')
>
> show()
>
>On OSX, it looks like the endianess is wrong because the colors are
>really off...
>
>
This was actually wrong in windows also, read and blue had switched.
By using this draw, it is corrected.
def draw(self):
"""
Draw the figure using the renderer
"""
FigureCanvasAgg.draw(self)
self.stringBuffer = str(self.buffer_rgba())
wrongqimage = qt.QImage(self.stringBuffer,
self.renderer.width,
self.renderer.height,
32,
None,
0,
qt.QImage.IgnoreEndian)
self.qimage = wrongqimage.swapRGB()
self.update()
That probably leaves us with the OSX problems, though. Ahh, fixed in
CVS, ok then.
>Also, I took a quick at the qimage class docs at
>http://doc.trolltech.com/3.3/qimage.html and saw
>
> It is one of the two classes Qt provides for dealing with images, the
> other being QPixmap. QImage is designed and optimized for I/O and for
> direct pixel access/manipulation. QPixmap is designed and optimized
> for drawing. There are (slow) functions to convert between QImage and
> QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().
>
>Does this suggest that QPixmap might be more appropriate / faster
>since you don't need to do the individual pixel manipulation provided
>by QImage (spoken as a total qt newbie, so please forgive any
>stupidities on my part...)
>
>
>
I think that QPixmap or better yet QCanvas would be the appropriate if
you are making a pure Qt-backend, but that QImage is the choice for a
backend with other rendering as Agg or Cairo.
>An unrelated observation regarding event handling: the qt backend is
>not connecting to mouse motion unless a pan/zoom button is pressed and
>released, eg coords_demo.py does not work properly.
>
>
>
Adding this to the end of FigureCanvasQtAgg.__init__ will fix tracking:
self.setMouseTracking(True)
Regards,
Sigve
|
|
From: Ted D. <ted...@jp...> - 2005-01-31 17:55:25
|
We've also been working on a Qt front end. It's been going slow because
we've only been able to spend about 1 oerson-day per week on it. But,
starting this week I have someone full time on it. He's gotten a basic
widget working using the same organization that the GTK code
uses. Sigve's code has a lot more functionality in the tool bars than
ours right now.
Here's where we're at:
- Finished C++ routine to convert AGG -> QPixmap (in /src/_qtagg.cpp)
- Finished low level widget to display the AGG pixmap using a widget
derived from QLabel (in ./lib/matplotlib/backends/backend_qtagg.py)
- Working on a higher level window widget to display the plot and the tool
bar. We implemented the tool bar as a Qt tool bar which allows you drag it
around, detach it, etc.
The guy working on it doesn't think it would take more than a day or two to
incorporate Sigve's code for the tool bar handling into our code. We're
close enough to finishing that it probably doesn't make a lot of sense to
try and set up a collaboration right now but I'm open to that possibility
if that's what people want. All I really interested in is seeing the QtAgg
front end in matplotlib as a supported component (which we'd be happy to
help maintain) so whatever gets us there the quickest sounds good to me.
Ted
PS: here's the code we used to do the AGG->QPixmap conversion. It may not
be the fastest way to do it but it does work which is all we were after for
the first cut.
PyQObject* pyDrawable = static_cast< PyQObject* >( args[0].ptr() );
QLabel* label = static_cast< QLabel* >( pyDrawable->obj );
RendererAgg* aggRenderer = static_cast< RendererAgg* >( args[1].ptr() );
unsigned int width = aggRenderer->get_width();
unsigned int height = aggRenderer->get_height();
QImage image( aggRenderer->pixBuffer, width, height, 32, 0, 256,
QImage::LittleEndian );
QPixmap pixmap;
pixmap.convertFromImage( image, QPixmap::Color );
label->setPixmap( pixmap );
At 07:25 AM 1/31/2005, John Hunter wrote:
> >>>>> "John" == John Hunter <jdh...@ac...> writes:
>
> John> * The only explanation I can think of for why the colors
> John> are wrong is that qt has a different byte order for images
> John> than you are getting from agg (is could it be bgra instead
> John> of rgba, or that something is wrong with the endianess...)
> John> If you need a different byte ordering /pixel format, I can
> John> provide the required method in the agg backend. I note that
> John> the saved figures *do* have the right color scheme, which
> John> supports this idea.
>
>Another clue that endianess is playing a role here is that the colors
>are dramatically different on OSX (which I tested yesterday) ans linux
>which I tested today. But I think it's more than an endian problem,
>because the colors are wrong on both platforms. On linux, it looks
>like the endianess is right, but it's an rgb versus bgr thing, since
>the colors are backwards on
>
> from pylab import *
> subplot(211)
> plot([1,2,3], color='red')
>
> subplot(212)
> plot([1,2,3], color='blue')
>
> show()
>
>On OSX, it looks like the endianess is wrong because the colors are
>really off...
>
>Also, I took a quick at the qimage class docs at
>http://doc.trolltech.com/3.3/qimage.html and saw
>
> It is one of the two classes Qt provides for dealing with images, the
> other being QPixmap. QImage is designed and optimized for I/O and for
> direct pixel access/manipulation. QPixmap is designed and optimized
> for drawing. There are (slow) functions to convert between QImage and
> QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().
>
>Does this suggest that QPixmap might be more appropriate / faster
>since you don't need to do the individual pixel manipulation provided
>by QImage (spoken as a total qt newbie, so please forgive any
>stupidities on my part...)
>
>
>An unrelated observation regarding event handling: the qt backend is
>not connecting to mouse motion unless a pan/zoom button is pressed and
>released, eg coords_demo.py does not work properly.
>
>Cheers!
>JDH
>
>
>-------------------------------------------------------
>This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
>Tool for open source databases. Create drag-&-drop reports. Save time
>by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
>Download a FREE copy at http://www.intelliview.com/go/osdn_nl
>_______________________________________________
>Matplotlib-devel mailing list
>Mat...@li...
>https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
Ted Drain Jet Propulsion Laboratory ted...@jp...
|
|
From: John H. <jdh...@ac...> - 2005-01-31 15:34:50
|
>>>>> "John" == John Hunter <jdh...@ac...> writes:
John> * The only explanation I can think of for why the colors
John> are wrong is that qt has a different byte order for images
John> than you are getting from agg (is could it be bgra instead
John> of rgba, or that something is wrong with the endianess...)
John> If you need a different byte ordering /pixel format, I can
John> provide the required method in the agg backend. I note that
John> the saved figures *do* have the right color scheme, which
John> supports this idea.
Another clue that endianess is playing a role here is that the colors
are dramatically different on OSX (which I tested yesterday) ans linux
which I tested today. But I think it's more than an endian problem,
because the colors are wrong on both platforms. On linux, it looks
like the endianess is right, but it's an rgb versus bgr thing, since
the colors are backwards on
from pylab import *
subplot(211)
plot([1,2,3], color='red')
subplot(212)
plot([1,2,3], color='blue')
show()
On OSX, it looks like the endianess is wrong because the colors are
really off...
Also, I took a quick at the qimage class docs at
http://doc.trolltech.com/3.3/qimage.html and saw
It is one of the two classes Qt provides for dealing with images, the
other being QPixmap. QImage is designed and optimized for I/O and for
direct pixel access/manipulation. QPixmap is designed and optimized
for drawing. There are (slow) functions to convert between QImage and
QPixmap: QPixmap::convertToImage() and QPixmap::convertFromImage().
Does this suggest that QPixmap might be more appropriate / faster
since you don't need to do the individual pixel manipulation provided
by QImage (spoken as a total qt newbie, so please forgive any
stupidities on my part...)
An unrelated observation regarding event handling: the qt backend is
not connecting to mouse motion unless a pan/zoom button is pressed and
released, eg coords_demo.py does not work properly.
Cheers!
JDH
|
|
From: Steve C. <ste...@ya...> - 2005-01-31 09:56:27
|
The gdk.threads_init() entry in the pygtk manual says: http://www.pygtk.org/pygtk2reference/gdk-functions.html#function-gdk-- threads-init "PyGTK does not release the GIL when calling a GTK or GDK function. Also it does not acquire the GDK global lock (GGL). This means that, in effect, Python threads can use the GIL alone to serialize access to the GTK and GDK libraries. Of course, if there are non-Python threads calling GTK or GDK functions the GGL must be used." I read this to mean that Python programs with no non-Python threads, like matplotlib, can run gtk.main in its own thread and do not need to use gtk_protect (for gdk.threads_enter/leave GGL locking) since the Python GIL will serialise access to GTK/GDK libraries. That would be an easy solution to the interactive GTK problem - just start gtk.main in its own thread with no need to alter any other code! It sounds too simple to be true, have I missed something? Steve |
|
From: John H. <jdh...@ac...> - 2005-01-31 04:11:22
|
>>>>> "Sigve" == Sigve Tjora <pu...@tj...> writes:
Sigve> Hi, I have written a basic QtAgg backend for
Sigve> Matplot-lib. It is only tested on Windows, so some more
Sigve> testing should be done, but it is my hope that it can some
Sigve> day be included in the matplotlib distribution. I will test
Sigve> on linux when I get the time, but all the code is python so
Sigve> it should probably work ok.
Indeed -- it's a testament to QT and python that the untested code
appears to run the same on linux (per Steve's report) and OS X, which
I tested today. Good work!
Sigve> See http://www.tjora.no/python/matplotlib/ for the code.
Sigve> Most examples run ok, but the keypress_demo.py does not
Sigve> work yet. Not all examples have been tested, just some
Sigve> random double-clicking on the one that look interesting.
I think the problem here was that you had
def keyPressEvent(self, ev):
self.keyPressEvent(ev.text())
def keyReleaseEvent(self, ev):
self.keyReleaseEvent(ev.text())
where you meant
def keyPressEvent(self, ev):
self.key_press_event(ev.text())
def keyReleaseEvent(self, ev):
self.key_release_event(ev.text())
I made these changes in CVS, and the keypress_demo indeed works.
Sigve> A lot of the comments from the backend_template.py has not
Sigve> been removed or fixed. The code is also somewhat rough
Sigve> around the edges, but it works.
Sigve> Is there any unittest-suite it is possible to run the
Sigve> backend against?
The standard test suite is examples/backend_driver. You just need to
set the "backends" list to the list of backends you want to test. Eg
backends = ['QtAgg']
Sigve> Feedback is welcome.
I agree with most of the comments Steve made.
* I think factoring the class into a module that handles the qt
widgets, and have a small module that does qtagg would be a good
thing. Steve would likely do a qtcairo backend if you did this...
* The only explanation I can think of for why the colors are wrong
is that qt has a different byte order for images than you are
getting from agg (is could it be bgra instead of rgba, or that
something is wrong with the endianess...) If you need a different
byte ordering /pixel format, I can provide the required method in
the agg backend. I note that the saved figures *do* have the
right color scheme, which supports this idea.
* The control key modifier is apparently not recognized -- this
provides aspect ratio preserving zoom. I can't test any of the
right click drag functionality right now, actually, since I'm on a
mac w/o an external mouse plugged in **&$$ macs!
Thanks!
JDH
|
|
From: Baptiste C. <bap...@al...> - 2005-01-30 23:13:52
|
John Hunter a =E9crit : > I have added some changes to CVS to support sharex and sharey kwargs > (I thought this was a better name than twinx and twiny). I had to > make some minor changes to axis to support sharing tick locators and > formatters, but nothing substantial. You can now instantiate an axes > with, eg >=20 > subplot(212, sharex=3Dax1) >=20 > and ditto for sharey. The view limits, transform function, and tick > Locator and Formatter are shared. This allows you to pan and zoom on > one axes and have the others follow, which is very nice. There is a > new example showing how to use this example/shared_axis_demo.py. >=20 Hi John, I like this implementation a lot. Cool stuff ! > I was able to remove the TwinAxes class altogether and use the shared > kwargs in its stead, which is cleaner. I preserved the "twin" > convenience function (naming it twinx) and all it does is pass the > proper kwargs and make the calls to tick_right. > examples/two_scales.py is updated >=20 you also need to call tick_left on the original axis, but that is a=20 minor correction. > I don't think the datalim need to be shared because they are > responsible only for autoscaling. > There is still a problem because autoscaling is disabled on the second=20 axes. I have an idea on how to solve this, I'll try it and send a patch=20 later in the week. > One possibility is to leave inaxes, xdata and ydata alone which > satisfies both problems above. And then to add a new attribute, axseq > which is a list of (ax, xdata, ydata ) tuples to handle the > overlapping axes case. Internally, we could use axseq so that pan/zoom > will be handled properly in the two_scales case. The draw back here > is that having more than one obvious way to do it may also confuse > people down the road. >=20 This sounds reasonable to me. I don't think it is confusing. If people=20 know what to do with multiple axes, they'll go with axseq, if not=20 inaxes, xdata and ydata will provide the most reasonable choice for them. I'll play a little bit with this, and see if it breaks anything I use. Cheers, BC |
|
From: Fernando P. <Fer...@co...> - 2005-01-30 23:00:36
|
Baptiste Carvello wrote: > Hi, >=20 > Steve Chaplin a =E9crit : >>When thinking about using threads for interactive mode I had been >>assuming people using the interactive mode would be using the pylab >>interface, does anyone use the matplotlib class interface in interactiv= e >>mode? >> >=20 > I sometimes do. Agreed. One should also be able to execute interactively large scripts which may = have=20 been written to the OO interface. I know that I routinely test 10k LOC= =20 modules from within ipython (though not matplotlib based). It would be I= MHO=20 poor design to put all sorts of special-case warnings, where certain feat= ures=20 of matplotlib would only be available in certain ways of using it. Speci= al=20 cases lead to madness... Note that I haven't followed the details close enough to vouch for any=20 particular approach. I just would like to see any solution implemented t= o be=20 as clean and general as possible. As far as users are concerned, these=20 details should be, where possible, totally irrelevant (internal implement= ation=20 only). As a reference, ipython tries mightily hard to make sure that _an= y_=20 code which can be executed at a system command line as 'python foo.py'=20 produces identical behavior at an ipython prompt via 'run foo'. There ar= e=20 special options to 'run' for modifying this, but the default attempts to=20 emulate python very faitfully, just with better tracebacks, debug support= ,=20 etc. And I consider deviations from this bevavior as bugs. It's not 100= %=20 perfect, but it really works fairly well in most cases. Regards, f |
|
From: Baptiste C. <bap...@al...> - 2005-01-30 22:47:31
|
Hi,
Steve Chaplin a =E9crit :
> What situation would yield an "Xlib async reply"?
> =20
using your mt module:
>>> import mt
>>> mt.gui_cmd('print "OK"')
OK
>>> import matplotlib
>>> matplotlib.interactive(1)
>>> import pylab
Xlib: unexpected async reply (sequence 0x4b)!
This is on linux, I don't know what you get on other platforms, but I=20
guess it's just as bad.
> How does it break method calls of matplotlib objects? In interactive
> mode the gtk backend does not work (by itself) so there's nothing to
> break
Well, it depends on how ambitious you are :-)
> When thinking about using threads for interactive mode I had been
> assuming people using the interactive mode would be using the pylab
> interface, does anyone use the matplotlib class interface in interactiv=
e
> mode?
>=20
I sometimes do. However, I've painted the situation worse than it is. I=20
almost only use the setter/getter methods, which are not dangerous.
One annoying thing though: error_msg will hang the gui:
>>> import mt
>>> mt.gui_cmd('from pylab import *')
>>> mt.gui_cmd('plot([1,2])')
>>> mt.gui_cmd('plot([1,2],"0r")')
*** gui hangs here, you get the prompt back, but no gui commands will=20
work ***
> In import_gtk() there is time.sleep(1) - what is that for?
>=20
This is an attempt to avoid a race condition were a proxy function would=20
be called before the GTK thread is initialized. I don't know if this=20
would lead to a real problem. 1s wait not that bad anyway.
> Shouldn't widget creation be protected as well by wrapping things like
> new_figure_manager() and FigureCanvasGTK(). I know __init__ is wrapped
> but objects may have __new__ methods which call gdk/gtk functions befor=
e
> __init__ is called.
>=20
I didn't think of that. Most GTK object are not dangerous until they are=20
shown.
> How about if a widgets standard methods such as show(), present() etc
> are used - they are not protected (unless called from a protected
> method). I think this just applies to using the class interface in
> interactive mode, so it may be rarely encountered but might be a
> problem.
>=20
As I stated, I didn't try to protect methods inherited from GTK objects=20
(ie not defined in matplotlib). Which means people using them are on=20
their own. You have to draw the boundary somewhere, unless you want to=20
implement a full gui_thread.
> Why use gtk_protect(), exec() and GTK_TEMPLATE, when you could use:
>=20
> def gtk_protect (fun):
> def decorator (*args, **kwargs):
>
Well this was a try to set the proxy function name as the real function=20
name, in order to avoid weirdeness when reading object help. But I could=20
not set the argument spec correctly, so I ended up adding the 'proxy=20
from' line to the docstring. So I think all the GTK_TEMPLATE machinery=20
serves no purpose now.
As a final note, I have to say that the latest version of interactive.py=20
is good enough for my needs, so I'm no longer very motivated for pushing=20
this patch.
If you just need the pylab interface, you can also do it without=20
patching matplotlib. Just create a protected_pylab.py module, where you=20
would start the gui thread, define the gtk_protect function, import=20
pylab and define command=3Dgtk_protect(pylab.command) for every command i=
n=20
pylab. Then doing 'from protected_pylab import *' would give you a=20
working pylab interface, with just the error_msg problem.
Cheers,
Baptiste
|
|
From: Fernando P. <Fer...@co...> - 2005-01-30 18:43:40
|
Steve Chaplin wrote: > To run a background process as a thread you would need to redirect its > stdout somewhere (StringIO for example). The problem with using threads > for this is that they share the stdout with the main thread, so if you > redirect the background threads stdout you will redirect the python > interpreters stdout too! > You could run a background process as an actual process and not a thread > (and Python 2.4 has a new subprocess module which unifies the previous > solutions of os.system, os.spawn*, os.popen*, popen2.*, commands.*). It > lets you redirect stdout, but is used for running executables, not > calling python functions. > > It has me stumped too, how can you call a python function and redirect > its stdout independent of the python interpreters stdout? Not as far as I know. That's why I think the only solution for the whole 'backgrounding' problem with stdout is to put everything into a gui window (a la mathematica notebooks). I've been thinking about it, and the proper way to write it is probably with _two_ python processes. One would be the gui environment, and the other would be just a 'kernel' executing commands. The stdout of the kernel would then be connected to an object capable of putting the results of each command next to the input cell which generated them. I bet that's pretty much how Mathematica is organized, simply because it looks like the only reasonable way to deal with the issue. Cheers, f |
|
From: Steve C. <ste...@ya...> - 2005-01-30 12:45:46
|
On Fri, 2005-01-28 at 21:36 +0100, Sigve Tjora wrote: > Hi, > I have written a basic QtAgg backend for Matplot-lib. It is only tested > on Windows, so some more testing should be done, but it is my hope that > it can some day be included in the matplotlib distribution. I will test > on linux when I get the time, but all the code is python so it should > probably work ok. Well done. I tried it out on Linux (Fedora 3) and it works reasonably well. I noticed a few things: It puts the toolbar at the top rather than the bottom of the window. The graph is smaller and the colours are different than that produced with GTKAgg, which is strange since they both use Agg rendering. I think it would be better to have a 'backend_qt.py' file used as a base class (with a FigureCanvasQtAgg.draw() method that raises NotImplementedError), and with backend_qtagg.py overriding just those functions/methods which are specific to drawing using Agg. This would allow backend_qt.py code to be used to produce a QtCairo backend at a later date. I copied the file into cvs so other people can try it out. Regards Steve |
|
From: Steve C. <ste...@ya...> - 2005-01-30 08:37:08
|
On Wed, 2005-01-26 at 22:18 +0100, Baptiste Carvello wrote:
I've finally got round installing the interactive gui thread patch to
have a look at it. It worked quite well for a few simple plots I tried.
> A bug in the handling of threads_enter()/threads_leave() leads to a
> deadlock, while a bug with a gui thread yields "Xlib async reply".
> Choose which ugly death you prefer !
What situation would yield an "Xlib async reply"?
> There are several strategies:
...
> * wrap only pylab functions (draw_if_interactive etc), as you seem to
> suggest in your second email: imho this is not acceptable because it
> breaks method calls of matplotlib objects
How does it break method calls of matplotlib objects? In interactive
mode the gtk backend does not work (by itself) so there's nothing to
break, and in non-interactive mode the gui_cmd() function would not be
used.
When thinking about using threads for interactive mode I had been
assuming people using the interactive mode would be using the pylab
interface, does anyone use the matplotlib class interface in interactive
mode?
I have a few questions about patch itself:
In import_gtk() there is time.sleep(1) - what is that for?
Shouldn't widget creation be protected as well by wrapping things like
new_figure_manager() and FigureCanvasGTK(). I know __init__ is wrapped
but objects may have __new__ methods which call gdk/gtk functions before
__init__ is called.
How about if a widgets standard methods such as show(), present() etc
are used - they are not protected (unless called from a protected
method). I think this just applies to using the class interface in
interactive mode, so it may be rarely encountered but might be a
problem.
Why use gtk_protect(), exec() and GTK_TEMPLATE, when you could use:
def gtk_protect (fun):
def decorator (*args, **kwargs):
if IN_GTK or threading.currentThread() is Thread:
return fun(*args, **kwargs)
IN_GTK.append (fun)
gtk.threads_enter()
try:
res = fun(*args, **kwargs)
finally:
gtk.threads_leave()
IN_GTK.pop()
return res
return decorator
Steve
|
|
From: Steve C. <ste...@ya...> - 2005-01-30 03:44:08
|
On Thu, 2005-01-27 at 17:14 -0700, Fernando Perez wrote: > > - runsource() and runcode() are synchronised using wait()/notify() so > > they deal with one code object at a time. If self.code_to_run is changed > > to a code queue (using list.append() and list.pop(0)) then the wait > > ()/notify() could be removed and the interpreter thread would return > > immediately it adds the code to self.code_to_run and not when the main > > thread has executed the code. > > On second thought, I don't think this is a good idea in general. The problem > I see is the serialization of output. Imagine you start a long running job > and you get the prompt back right away. If your job prints to stdout along > the way (as is very common with scientific codes), your input line will get > clobbered by this output. > > If you could run in a gui window where you could associate the stdout for each > input 'cell' with its own output one, it would be different. This is exactly > how Mathematica notebooks work, they stack a queue of cells for running > sequentially, you get your typing prompt back immediately, but the output of > each command is collected in an Out[] cell next to the corresponding In[] one. > In a plain terminal, I don't see how we can make this work (in fact, in a > terminal Mathematica also serializes output for this very reason). > > I have been toying with the idea of adding a way to 'background' processes > automatically to ipython, by creating a list of worker threads for long > running jobs. But the problem of handling stdout has me stumped. > > I'm open to comments, though, or perhaps I'm missing something obvious here. So removing wait()/notify() would not be such a good idea, it might be useful if you are only running gui code, but not when the command prints to stdout. To run a background process as a thread you would need to redirect its stdout somewhere (StringIO for example). The problem with using threads for this is that they share the stdout with the main thread, so if you redirect the background threads stdout you will redirect the python interpreters stdout too! You could run a background process as an actual process and not a thread (and Python 2.4 has a new subprocess module which unifies the previous solutions of os.system, os.spawn*, os.popen*, popen2.*, commands.*). It lets you redirect stdout, but is used for running executables, not calling python functions. It has me stumped too, how can you call a python function and redirect its stdout independent of the python interpreters stdout? Steve |
|
From: Sigve T. <pu...@tj...> - 2005-01-28 20:37:33
|
Hi, I have written a basic QtAgg backend for Matplot-lib. It is only tested on Windows, so some more testing should be done, but it is my hope that it can some day be included in the matplotlib distribution. I will test on linux when I get the time, but all the code is python so it should probably work ok. See http://www.tjora.no/python/matplotlib/ for the code. Most examples run ok, but the keypress_demo.py does not work yet. Not all examples have been tested, just some random double-clicking on the one that look interesting. A lot of the comments from the backend_template.py has not been removed or fixed. The code is also somewhat rough around the edges, but it works. Is there any unittest-suite it is possible to run the backend against? Feedback is welcome. Best regards, Sigve Tjora |
|
From: Steve C. <ste...@ya...> - 2005-01-28 07:05:53
|
On Thu, 2005-01-27 at 11:43 -0600, John Hunter wrote:
> I probably just forgot to update interactive.py last time Fernando
> sent it to me. Feel free to do update interactive.py and its
> interface and command line args (eg, pylab or not) as you see fit.
> Just update the changelog so I can include them in the next release
> notes.
>
> After you're done, you may want to take a look at interactive.html
> and/or \section{Interactive} of the user's guide, and make updates as
> you see fit.
I replaced examples/interactive.py with Fernando's updated version
(adding a comment that gtk.main runs in the main thread and replacing
gtk.timeout_add with gobject.timeout_add).
I looked at interactive.html.template and user_guide.tex and saw a
reference to ipython, but no mention of interactive.py, so it does not
look like they need updating. I seem to recall interactive.py being
mentioned in the docs in the past, but they must have been changed since
then.
Steve
|
|
From: Fernando P. <Fer...@co...> - 2005-01-28 00:14:57
|
Steve Chaplin wrote: > On Tue, 2005-01-25 at 22:25 -0700, Fernando Perez wrote: > >>In case anyone is interested, here's a lightweight, standalone (non-ipython) >>GTK threaded interactive interpreter with matplotlib support. This code is >>also based on the same ASPN recipe, it's basically the prototype I used to >>understand that recipe when I was adding the matplotlib support to IPython. > > Thanks, its a good example of code.InteractiveConsole, when I saw codeop in > the ASPN recipe I wondered why code.py was not used. > > I noticed a few small points: > - GTKInterpreter says "Run a gtk mainloop() in a separate thread.", yet > gtk.main() runs in the main thread, and the interpreter/console runs in > a separate thread. You are correct. > - gtk.timeout_add() is now deprecated in favour of gobject.timeout_add() Feel free to fix it, I didn't know better. > - runsource() and runcode() are synchronised using wait()/notify() so > they deal with one code object at a time. If self.code_to_run is changed > to a code queue (using list.append() and list.pop(0)) then the wait > ()/notify() could be removed and the interpreter thread would return > immediately it adds the code to self.code_to_run and not when the main > thread has executed the code. On second thought, I don't think this is a good idea in general. The problem I see is the serialization of output. Imagine you start a long running job and you get the prompt back right away. If your job prints to stdout along the way (as is very common with scientific codes), your input line will get clobbered by this output. If you could run in a gui window where you could associate the stdout for each input 'cell' with its own output one, it would be different. This is exactly how Mathematica notebooks work, they stack a queue of cells for running sequentially, you get your typing prompt back immediately, but the output of each command is collected in an Out[] cell next to the corresponding In[] one. In a plain terminal, I don't see how we can make this work (in fact, in a terminal Mathematica also serializes output for this very reason). I have been toying with the idea of adding a way to 'background' processes automatically to ipython, by creating a list of worker threads for long running jobs. But the problem of handling stdout has me stumped. I'm open to comments, though, or perhaps I'm missing something obvious here. Best, f |
|
From: John H. <jdh...@ac...> - 2005-01-27 22:12:38
|
>>>>> "Baptiste" == Baptiste Carvello <bap...@al...> writes:
>>
Baptiste> That sounds like a good syntax. Its not a problem the
Baptiste> share the x/ylims. As long as you can get the lazy
Baptiste> values at Axes creation, you can set the transforms
Baptiste> correctly. The question is whether or not to share the
Baptiste> Axis instance. If you do, you will have trouble drawing,
Baptiste> if you don't, you have trouble when you want to change
Baptiste> the attributes (see below). I got away with this only
Baptiste> because I have to draw only one "physical" axis.
Hi Baptiste,
After reading your email and studying your patch more, I now see how
to generalize this to the case of non-overlapping axes which share
either the x or y axis, eg ganged plots.
I have added some changes to CVS to support sharex and sharey kwargs
(I thought this was a better name than twinx and twiny). I had to
make some minor changes to axis to support sharing tick locators and
formatters, but nothing substantial. You can now instantiate an axes
with, eg
subplot(212, sharex=ax1)
and ditto for sharey. The view limits, transform function, and tick
Locator and Formatter are shared. This allows you to pan and zoom on
one axes and have the others follow, which is very nice. There is a
new example showing how to use this example/shared_axis_demo.py.
I was able to remove the TwinAxes class altogether and use the shared
kwargs in its stead, which is cleaner. I preserved the "twin"
convenience function (naming it twinx) and all it does is pass the
proper kwargs and make the calls to tick_right.
examples/two_scales.py is updated
Baptiste> I'm starting to wonder which properties of Axis we
Baptiste> really want to share between axes: limits, scale
Baptiste> (linear/log), fmtdata, label, tick positions (thus a
Baptiste> common "tick factory"), tick label texts, viewLim,
Baptiste> dataLim (we need to think about update_datalim).
Baptiste> and which we do *not* want to share: all graphic
Baptiste> objects, visibility of labels (ticks ?), style of ticks
Baptiste> and tick labels (you may want smaller fonts in an
Baptiste> inset), type of axis (XAxis, YAxis, ThetaAxis, Color,
Baptiste> ..., for ex. we may want to plot z(x,y) as pcolor and
Baptiste> z(x) as line with shared z lims)
Baptiste> Maybe we want to split an axis into 2 objects ? I need
Baptiste> to think more about this.
I don't think the datalim need to be shared because they are
responsible only for autoscaling. The new approach allows the
different axes to have different properties on their labels, eg font
size as you mentioned. While you cannot turn off labels selectively
on one axes with
set(ax2, xticklabels=[])
because this changes the Formatter which is shared, you can achieve
the same effect by setting the visibility property, which is not
shared
set( ax2.get_xticklabels(), visible=False)
examples/ganged_plots.py, examples/two_scales.py, and
examples/shared_axis_demo.py show off the new features.
Let me know if this design covers the use cases you can think of.
Baptiste> This is uncorrelated, and probably easier than the one
Baptiste> above. We would need to modify event.inaxes to be a list
Baptiste> (in backend_bases), and act upon all those axes in
Baptiste> pan/zoom. When only one axes can be used (for ex. the
Baptiste> coordinates of the mouse in the status bar), we would
Baptiste> use event.inaxes[0], or maybe the most recently used
Baptiste> axes (more difficult, but maybe more consistent...we'll
Baptiste> see at implementation time).
Yes, this needs to be fixed and it is not very hard to do. There are
three event variables affected, inaxes, xdata and ydata, the latter
two give the data coords of the point in the axes the mouse is over.
As you know, the problem is that the current implementation only
registers the first axes and then breaks out of the loop. It would be
easy to fix this but I'm worried about two things: backward
compatibility (not a huge problem since only power users are using
this feature) and ease of use. It is really a corner case to be over
multiple axes, and I am hesitant to force the newbie to deal with this
in the typical case when there are no overlapping axes.
One possibility is to leave inaxes, xdata and ydata alone which
satisfies both problems above. And then to add a new attribute, axseq
which is a list of (ax, xdata, ydata ) tuples to handle the
overlapping axes case. Internally, we could use axseq so that pan/zoom
will be handled properly in the two_scales case. The draw back here
is that having more than one obvious way to do it may also confuse
people down the road. For clarity, the two interfaces I'm discussing are
def callback1(event): # current impl.
if event.inaxes is not None:
do_something with event.inaxes, event.xdata, event.ydata
def callback2(event): # candidate impl.
for ax, xdata, ydata in event.axseq:
do_something with ax, xdata, ydata
I'm weakly inclined to break backward compatibility and go with the
cleaner, comprehensive design in callback2, which on the face of it
doesn't look too hard to use.
Suggestions?
JDH
|
|
From: John H. <jdh...@ac...> - 2005-01-27 17:52:14
|
>>>>> "Steve" == Steve Chaplin <ste...@ya...> writes:
Steve> John, this looks like an much improved interactive.py, is
Steve> it OK to use it to replace interactive.py in cvs, and if so
Steve> should the '-pylab' option be left as it is or removed to
Steve> be compatible with the current interactive.py?
Hey Steve,
I probably just forgot to update interactive.py last time Fernando
sent it to me. Feel free to do update interactive.py and its
interface and command line args (eg, pylab or not) as you see fit.
Just update the changelog so I can include them in the next release
notes.
After you're done, you may want to take a look at interactive.html
and/or \section{Interactive} of the user's guide, and make updates as
you see fit.
Thanks!
JDH
|
|
From: Fernando P. <Fer...@co...> - 2005-01-27 17:12:12
|
Steve Chaplin wrote: > On Tue, 2005-01-25 at 22:25 -0700, Fernando Perez wrote: > >>In case anyone is interested, here's a lightweight, standalone (non-ipython) >>GTK threaded interactive interpreter with matplotlib support. This code is >>also based on the same ASPN recipe, it's basically the prototype I used to >>understand that recipe when I was adding the matplotlib support to IPython. > > Thanks, its a good example of code.InteractiveConsole, when I saw codeop in > the ASPN recipe I wondered why code.py was not used. > > I noticed a few small points: > - GTKInterpreter says "Run a gtk mainloop() in a separate thread.", yet > gtk.main() runs in the main thread, and the interpreter/console runs in > a separate thread. > - gtk.timeout_add() is now deprecated in favour of gobject.timeout_add() > > - runsource() and runcode() are synchronised using wait()/notify() so > they deal with one code object at a time. If self.code_to_run is changed > to a code queue (using list.append() and list.pop(0)) then the wait > ()/notify() could be removed and the interpreter thread would return > immediately it adds the code to self.code_to_run and not when the main > thread has executed the code. I am _really_ ignorant of thread issues, and so I have avoided touching the threading part of this code at all, though I've always suspected it could be cleaner. Would you mind applying these fixes and sending it back my way (including the GTK stuff)? I could then port your improvements over to the code in ipython proper which implements this same functionality. Cheers, f |
|
From: Steve C. <ste...@ya...> - 2005-01-27 16:56:34
|
On Tue, 2005-01-25 at 22:25 -0700, Fernando Perez wrote: > In case anyone is interested, here's a lightweight, standalone (non-ipython) > GTK threaded interactive interpreter with matplotlib support. This code is > also based on the same ASPN recipe, it's basically the prototype I used to > understand that recipe when I was adding the matplotlib support to IPython. Thanks, its a good example of code.InteractiveConsole, when I saw codeop in the ASPN recipe I wondered why code.py was not used. I noticed a few small points: - GTKInterpreter says "Run a gtk mainloop() in a separate thread.", yet gtk.main() runs in the main thread, and the interpreter/console runs in a separate thread. - gtk.timeout_add() is now deprecated in favour of gobject.timeout_add() - runsource() and runcode() are synchronised using wait()/notify() so they deal with one code object at a time. If self.code_to_run is changed to a code queue (using list.append() and list.pop(0)) then the wait ()/notify() could be removed and the interpreter thread would return immediately it adds the code to self.code_to_run and not when the main thread has executed the code. > I think I sent this to John a while back so he could replace the > interactive.py shipped with matplotlib. I fully acknowledge in the header the > ASPN recipe as the origin of the threading solution. John, this looks like an much improved interactive.py, is it OK to use it to replace interactive.py in cvs, and if so should the '-pylab' option be left as it is or removed to be compatible with the current interactive.py? Steve |
|
From: Baptiste C. <bap...@al...> - 2005-01-27 01:36:39
|
John Hunter a =E9crit : > Here is what I think would be ideal, and I wanted to sketch some of > these ideas in hopes that you might have some ideas on how to apply > them. Basically, the idea is that we want one axes to be able to > share the x or y limits with another axes in a more general way. Your > approach works fine as long as the two axes are overlayed. It would > be nice if we could do something like >=20 > # separate axes > ax1 =3D subplot(211) > plot([1,2,3]) >=20 > ax2 =3D subplot(212, twinx=3Dax1) > plot([4,5,6]) >=20 That sounds like a good syntax. Its not a problem the share the x/ylims. As long as you can get the lazy=20 values at Axes creation, you can set the transforms correctly. The=20 question is whether or not to share the Axis instance. If you do, you=20 will have trouble drawing, if you don't, you have trouble when you want=20 to change the attributes (see below). I got away with this only because=20 I have to draw only one "physical" axis. > To do overlayed axes, you could do >=20 > # overalyed axes > ax1 =3D subplot(111) > plot([1,2,3]) >=20 > ax2 =3D subplot(111, twinx=3Dax1, yticks=3D'right') > plot([4,5,6]) >=20 OK, you also have to set the frame to off, we'll see the details later.=20 Maybe we can keep just the twin function in pylab.py as a shortcut. > I think this would be a nice consistent interface and in both cases > ax2 would share the xlim with ax1. As far as I can see, the only > thing getting in the way of extending your approach to handle this > case are the tick labels, since they would be in the wrong place for > ax2 in the separate axes case. For the separate axes case, you would > typically want tick labeling on the lower axes, but it would be ideal > to be able to control that as well. >=20 > I've been meaning to decouple the axis line and tick locations from > the main axes frame so that you could have offset labels and ticks. > Perhaps this would be a good time to make both changes together. >=20 That one is more tricky. All of matplotlib drawing model is based on the=20 premise that one objet draws at one given place. This has many=20 advantages. It allows the object to draw itself, which is good design.=20 It is also necessary for the cases where the final size matters (fonts,=20 linewidth). I don't think we want to change that. < I stopped here, thought about it for some time, went back later > I'm starting to wonder which properties of Axis we really want to share=20 between axes: limits, scale (linear/log), fmtdata, label, tick positions=20 (thus a common "tick factory"), tick label texts, viewLim, dataLim (we=20 need to think about update_datalim). and which we do *not* want to share: all graphic objects, visibility of=20 labels (ticks ?), style of ticks and tick labels (you may want smaller=20 fonts in an inset), type of axis (XAxis, YAxis, ThetaAxis, Color, ...,=20 for ex. we may want to plot z(x,y) as pcolor and z(x) as line with=20 shared z lims) Maybe we want to split an axis into 2 objects ? I need to think more=20 about this. > The other problem in the current implementation (and in your patch) > stems from the fact that for event handling, only one axes gets the > event. So in your two_scales.py example, if you pan/zoom the xlimits > behave correctly but only one axes gets the pan/zoom event for y. It > would be nice to pass these events on to all the axes the user is over > to handle the case of overlapping axes. >=20 This is uncorrelated, and probably easier than the one above. We would=20 need to modify event.inaxes to be a list (in backend_bases), and act=20 upon all those axes in pan/zoom. When only one axes can be used (for ex.=20 the coordinates of the mouse in the status bar), we would use=20 event.inaxes[0], or maybe the most recently used axes (more difficult,=20 but maybe more consistent...we'll see at implementation time). > Just some thoughts on what I think the proper behavior should be. If > you have any ideas on how to handle these, let me know. =20 >=20 well, we need to discuss that a little bit more, so we'll get a clearer=20 view of where we go :-) Cheers, Baptiste |
|
From: Baptiste C. <bap...@al...> - 2005-01-26 21:19:35
|
Steve Chaplin a =E9crit : > Regarding Baptiste's patch > - I'm not too keen on the idea of wrapping gtk.gdk.threads_enter() / > gtk.gdk.threads_leave() around every GDK function call. > - I share Fernando's concern with possible problems when adding new > widgets or embedding a matplotlib window into something else. >=20 > My understanding is that wrapping gtk.gdk.threads_enter() / > gtk.gdk.threads_leave() around GDK functions is not necessary if all th= e > GDK calls occur in the same thread. So I think a simpler solution is to > arrange for all gui calls to go to a single thread and do away with > enter()/leave(). >=20 This is mostly a question of taste. A bug in the handling of threads_enter()/threads_leave() leads to a=20 deadlock, while a bug with a gui thread yields "Xlib async reply".=20 Choose which ugly death you prefer ! > I created a module that allows interactive matplotlib access from a > python shell, its a modified version of > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109 >=20 In fact your module fits well into the framework of my proposal: all you=20 have to do is rename your gui_cmd to gtk_protect, and change a few=20 things like passing the function directly, passing the arguments, and=20 returning the value. Then you will have a drop-in replacement for=20 protect_mutex.py. > This method seems to work for me (on Linux) and is not very intrusive t= o > matplotlib code - it just requires that 'gui_cmd()' is used to execute > all gui commands when in interactive mode. >=20 This is where the real beef is. There are several strategies: * wrap everything: this is the examples/interactive.py strategy, simple,=20 but the gui freezes on long calculations * wrap all gui calls: this is the gui_thread strategy: elegant, but=20 difficult * wrap only pylab functions (draw_if_interactive etc), as you seem to=20 suggest in your second email: imho this is not acceptable because it=20 breaks method calls of matplotlib objects * draw the line somewhere in the backend: this is what I proposed. In the end, the backends developpers have the final say, because they=20 will have to do the day-to-day maintenance. > Any comments? >=20 > Regards > Steve >=20 Cheers, BC PS: tell me if I need to CC you or not |
|
From: John H. <jdh...@ac...> - 2005-01-26 19:57:41
|
>>>>> "Baptiste" == Baptiste Carvello <bap...@al...> writes:
Baptiste> Hello, I tried to improve the way of plotting two scales
Baptiste> (cf examples/two_scales.py). The attached patch contains
Baptiste> the following changes:
Hi Baptiste -- I applied your patch and am very impressed. It takes a
lot of hacking through matplotlib internals to get everything working
right together with transform, axis limits and the like. Your
approach is also a significant improvement over what we currently
have.
Here is what I think would be ideal, and I wanted to sketch some of
these ideas in hopes that you might have some ideas on how to apply
them. Basically, the idea is that we want one axes to be able to
share the x or y limits with another axes in a more general way. Your
approach works fine as long as the two axes are overlayed. It would
be nice if we could do something like
# separate axes
ax1 = subplot(211)
plot([1,2,3])
ax2 = subplot(212, twinx=ax1)
plot([4,5,6])
To do overlayed axes, you could do
# overalyed axes
ax1 = subplot(111)
plot([1,2,3])
ax2 = subplot(111, twinx=ax1, yticks='right')
plot([4,5,6])
I think this would be a nice consistent interface and in both cases
ax2 would share the xlim with ax1. As far as I can see, the only
thing getting in the way of extending your approach to handle this
case are the tick labels, since they would be in the wrong place for
ax2 in the separate axes case. For the separate axes case, you would
typically want tick labeling on the lower axes, but it would be ideal
to be able to control that as well.
I've been meaning to decouple the axis line and tick locations from
the main axes frame so that you could have offset labels and ticks.
Perhaps this would be a good time to make both changes together.
The other problem in the current implementation (and in your patch)
stems from the fact that for event handling, only one axes gets the
event. So in your two_scales.py example, if you pan/zoom the xlimits
behave correctly but only one axes gets the pan/zoom event for y. It
would be nice to pass these events on to all the axes the user is over
to handle the case of overlapping axes.
Just some thoughts on what I think the proper behavior should be. If
you have any ideas on how to handle these, let me know.
I just applied your two scales patch to CVS as an improved interim
solution.
Thanks!
JDH
|
|
From: Steve C. <ste...@ya...> - 2005-01-26 09:47:05
|
On Wed, 2005-01-26 at 12:17 +0800, Steve Chaplin wrote: > I created a module that allows interactive matplotlib access from a > python shell, its a modified version of > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109 > > This method seems to work for me (on Linux) and is not very intrusive to > matplotlib code - it just requires that 'gui_cmd()' is used to execute > all gui commands when in interactive mode. I may not have clearly explained my idea. I'm not proposing another Python shell/interpreter to run matplotlib. The mt.py module is to test an idea without needing to modify any matplotlib code. To use it as intended would involve moving it into matplotlib and getting matplotlib to call gui_cmd() to execute interactive gtk/gdk calls in their own thread. This is the part I'm not sure about - what is the minimal set of functions to wrap with gui_cmd() to ensure that it encloses all gtk/gdk functions? gui_cmd() could be called from draw_if_interactive() and maybe new_figure_manager(), I'm not sure where else it might be needed. Also it would need to be fed import commands. Steve |