Canvas coordinates vs. Plot coordinates

Dear Group,

What I need to do is to

  1. produce a plot (DONE)
  2. fix it so that mouse clicks in the canvas append the x coordinate of the click to a list (DONE)
  3. add a couple of buttons to the GUI, to reset the list and to kill the window (DONE)

So I’m pretty successful so far. The only problem is that the coordinates are in canvas coordinates, not plot coordinates. Now, rather embarrassingly, I can’t figure out how to get this right. It seems to be the case that all the examples are in plot coordinates. As of course is the readout in the GUI itself. Is there a simple way to fix this or do I have convert it to some other backend? Or use something else instead of FigureCanvasGTK? This, to me, made the most sense to me at the time of writing, although I must confess I’m still pretty new to this.

I paste some stripped down code below.

Thanks in advance,
Matthew

#!/usr/bin/env python

import sys, os, string
import scipy as S
pygtk.require(‘2.0’)
import gtk
#MPL.use(‘GTKAgg’)
import pylab as P
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar

class Stuff:

def reset(self, widget, data=None):
    self.ranges= S.array([])
    print self.ranges

def delete_event(self, widget, event, data=None):
    print "delete event occurred"
    return False

def destroy(self, widget, data=None):
    gtk.main_quit()

def clickCanvas(self, widget, event):
    if event.button==1:
        self.ranges = S.append(self.ranges , event.x)
        print self.ranges

def ZoneSetup(self):

    x=S.rand(10)
    y=S.rand(10)

    win = gtk.Window()
    win.connect("delete_event", self.delete_event)
    win.connect("destroy", self.destroy)
    win.set_default_size(600,450)

    vbox = gtk.VBox()
    hbox = gtk.HBox()
    win.add(vbox)

    fig = P.Figure(figsize=(5,4), dpi=100)
    ax = fig.add_subplot(111)
    ax.plot(x, y, c='red', ls='-')

    canvas = FigureCanvas(fig)
    vbox.pack_start(canvas)
    toolbar = NavigationToolbar(canvas, win)
    hbox.pack_start(toolbar)

    bReset = gtk.Button("Reset")
    bQuit  = gtk.Button("Quit")
    hbox.pack_start(bReset, False, False, 0)
    hbox.pack_start(bQuit,  False, False, 0)

    vbox.pack_start(hbox, False, False)

    bReset.connect ("clicked", self.reset)
    bQuit.connect_object("clicked", gtk.Widget.destroy, win)
    canvas.connect("button_press_event", self.clickCanvas)

    win.show_all()
    gtk.main()

def __init__(self):

    self.ranges= S.array([])

a=Stuff()
a.ZoneSetup()
print a.ranges

Use mpl events -- they work across user interface toolkits and handle
stuff like which axes did you click in and what are the data
coordinates

def onclick(event):
    print 'axes', event.inaxes
    if event.inaxes is None: return
    print 'canvas', event.x, event.y
    print 'data', event.xdata, event.ydata

cid = fig.canvas.mpl_connect('button_press_event', onclick)

See matplotlib.backend_bases.Event and derived classes for details on
available attributes. See
matplotlib.backend_bases.FigureCanvasBase.mpl_connect for details on
valid signals,

···

On Tue, May 6, 2008 at 11:17 AM, Matthew Czesarski <matthew.czesarski@...287...> wrote:

So I'm pretty successful so far. The only problem is that the coordinates
are in canvas coordinates, not plot coordinates. Now, rather embarrassingly,
I can't figure out how to get this right. It seems to be the case that all
the examples are in plot coordinates. As of course is the readout in the
GUI itself. Is there a simple way to fix this or do I have convert it to
some other backend? Or use something else instead of FigureCanvasGTK? This,
to me, made the most sense to me at the time of writing, although I must
confess I'm still pretty new to this.

Use mpl events – they work across user interface toolkits and handle

stuff like which axes did you click in and what are the data

coordinates

Excellent, that did the trick. In just 2 minutes. :slight_smile: Thanks a lot.

Could I just chuck in one simple question: you may have noticed I am embedding everything in GTK. After calling gtk.main() is there any way I can modify the displayed window? Or do I have to bin the whole thing and start again?

Thanks for your help,
Matthew

Sorry, I don't really understand the question, but you can certainly
modify the gtk application, you will just need to do it in the gtk
loop, eg in an idle or timeout handler, or in a callback.

JDH

···

On Wed, May 7, 2008 at 7:41 AM, Matthew Czesarski <matthew.czesarski@...287...> wrote:

Could I just chuck in one simple question: you may have noticed I am
embedding everything in GTK. After calling gtk.main() is there any way I can
modify the displayed window? Or do I have to bin the whole thing and start
again?