Drawing ruler lines

if at renderer or at artist level. The rulers must follow

    > the mouse and everytime they are moved the contents
    > "below" them must be restored. I don't know how to do it
    > (to save the underlying contents before rendering the
    > ruler). Another matter is tranformation between data and
    > screen coordinates, how could I do it? I played a little
    > with events, line artist and with the renderer api but I
    > would welcome any clue from you.

matplotlib has very recently added the ability to do just what you
describe (save and restore a background region, selectively draw
certain artists). The details of this are discussed at the matplotlib
wiki http://www.scipy.org/wikis/topical_software/Animations.

Fortunately for you, there is already an Cursor class which uses these
new techniques; See examples/widgets/cursor.py in the last matplotlib
release which uses the Cursor class at
http://matplotlib.sf.net/matplotlib.widgets.html#Cursor. I suggest
studying the source code for the Cursor class in matplotlib.widgets.py
since it implements exactly what you describe and thus will serve as
a good example for you if you want to understand animation further.

There are two modes in the Cursor class: useblit=True and
useblit=False. The former uses the copy/restore region feature you
describe for fast animated drawing and is available in the GTKAgg
backend in the last matplotlib release and in TkAgg in matplotlib CVS.
With useblit=False, cursoring will work but will be slower. Let me
know which backend/GUI you plan to be using.

The other alternative is to use GUI native drawing on top of the
matplotlib FigureCanvas; for the wx backend, there is an example
illustrating this in examples/wxcursor_demo.py.

JDH

Hi!

Fortunately for you, there is already an Cursor class which uses these
new techniques; See examples/widgets/cursor.py in the last matplotlib

There are two modes in the Cursor class: useblit=True and
useblit=False. The former uses the copy/restore region feature you
describe for fast animated drawing and is available in the GTKAgg
backend in the last matplotlib release and in TkAgg in matplotlib CVS.

I've been looking at the example, great! Sadly I'm using wx as
my backend so I guess I would not be able to take advantage of
useblit=True.

The other alternative is to use GUI native drawing on top of the
matplotlib FigureCanvas; for the wx backend, there is an example
illustrating this in examples/wxcursor_demo.py.

This demo performs notably better for wx.

Thank you very much!
Regards,
Carlos

···

JDH

___________________________________________________________ 1GB gratis, Antivirus y Antispam Correo Yahoo!, el mejor correo web del mundo http://correo.yahoo.com.ar

The other alternative is to use GUI native drawing on top of the
matplotlib FigureCanvas; for the wx backend, there is an example
illustrating this in examples/wxcursor_demo.py.

It works almost ok, but there are some quirks when repainting the window, (i) sometimes
the rulers are not erased and (ii) they are not redrawn when the window is fully repainted,
for example after being covered/discovered by other window. I want to put the
ruler redrawing routine into the paint event handler in order to see if this solves the
problem (which is caused by odd sequences of xor or invert -in my case- line plots).
The wx canvas implements its paint event hadler as a private _OnPaint method.
As long as encapsulation is a concern I wouldn't invoke it directly. But I need
the canvas to be repainted > before < plotting rulers, so they
will be placed "on top" of the other figures. So Skip() won't work, cause it will call the
canvas painter later. Also, if inside the paint event handler I call canvas.draw() and then
plot the rulers -without Skip()'ing at the end-, the paint event is rethrown all the time
killing performance (everytime canvas.draw() is called). I guess the right solution is
to call the base class paint event handler through the event table (instead of some
Super._OnPaint() hack) and then simply draw my modest rulers. Do you know
how to do that without calling _onPaint?

Thank you in advance.
Regards,
Carlos

···

___________________________________________________________ 1GB gratis, Antivirus y Antispam Correo Yahoo!, el mejor correo web del mundo http://correo.yahoo.com.ar

The other alternative is to use GUI native drawing on top of the
matplotlib FigureCanvas; for the wx backend, there is an example
illustrating this in examples/wxcursor_demo.py.

Since you're using wxPython, you've given my a plumb opportunity to repeat what is in danger of becoming my litany:

  You should check out Matt Newville's MPlot package and my wxmpl module, both of which exist to simply embedding matplotlib in wxPython applications. Both of them provide user interaction bells and whistles, including crosshairs around the mouse position.

Each of the libraries takes a different approach to plotting and has different benefits and drawbacks, so I encourage you to evaluate each of them and select the one that best meets your needs. Even if neither of them fit the bill, you'll hopefully be able to learn something from looking through the source.

It works almost ok, but there are some quirks when repainting the window, (i) sometimes
the rulers are not erased and (ii) they are not redrawn when the window is fully repainted,
for example after being covered/discovered by other window. I want to put the
ruler redrawing routine into the paint event handler in order to see if this solves the
problem (which is caused by odd sequences of xor or invert -in my case- line plots).

I suspect that this is exactly what you need to do to solve the problem. My approach in wxmpl has been to stop drawing the crosshairs when the mouse is outside of the plot panel, which has allowed me to sidestep this particular problem.

The wx canvas implements its paint event hadler as a private _OnPaint method.
As long as encapsulation is a concern I wouldn't invoke it directly.

While I appreciate your concerns about breaking encapsulation, I don't think you'll have any problems overriding _OnPaint() to draw your crosshairs after the plot has been repainted. As I indicated earlier, there are ways to design around needing to do so, but they entail not drawing crosshairs when the mouse is not in the window.

Ken

···

On Aug 10, 2005, at 1:41 PM, Carlos Pita wrote: