On Tuesday 11 November 2008 09:03:30 am [EMAIL PROTECTED] wrote:
> Dear all,
>
> after looking around for a plotting library I found Matplotlib and I tried
> to create a gray scale image in a wxpython application. Looks good!
>
> Now I have to find a line in the image with mainly vertical orientation. To
> do this a crosshair cursor would be fine. In Pylab I found a SpanSelector
> which also looks promising.
>
> Unfortunately I failed in adding a crosshair cursor or a SpanSelector into
> my wxpython application figure.
>
> Does anyone have an example add hand showing me how to achieve this?

This may be more than you asked for...

I have a Toolbar subclass that adds a button to graphically select a subset 
from the data, its sort of similar to the zoom tool only it doesnt zoom. This 
is specific to Qt4, but maybe you will find it useful. Toolbar._init_toolbar 
adds a "Select" action, which is wired so that one corner of a rectangle is 
defined by the mouse press, the opposite by the mouse release:


class Toolbar(MplToolbar):

    def __init__(self, *args, **kwargs):
        pixmap = QtGui.QPixmap()
        pixmap.load(':/cross.png')
        mplCursors.SELECT_POINT = pixmap
        super(Toolbar, self).__init__(*args, **kwargs)


    def _init_toolbar(self):
        self.basedir = os.path.join(mpl.rcParams[ 'datapath' ],'images')

        a = self.addAction(self._icon('home.svg'), 'Home', self.home)
        a.setToolTip('Reset original view')
        a = self.addAction(self._icon('back.svg'), 'Back', self.back)
        a.setToolTip('Back to previous view')
        a = self.addAction(self._icon('forward.svg'), 'Forward', self.forward)
        a.setToolTip('Forward to next view')
        self.addSeparator()
        a = self.addAction(self._icon('move.svg'), 'Pan', self.pan)
        a.setToolTip('Pan axes with left mouse, zoom with right')
        a = self.addAction(self._icon('zoom_to_rect.svg'), 'Zoom', self.zoom)
        a.setToolTip('Zoom to rectangle')
        a = self.addAction(QtGui.QIcon(':/crosshairs.svg'), 'Select',
                           self.selectPointMode)
        a.setToolTip('Select the nearest data point')
        self.addSeparator()
        a = self.addAction(self._icon('subplots.png'), 'Subplots',
                self.configure_subplots)
        a.setToolTip('Configure subplots')
        a = self.addAction(self._icon('filesave.svg'), 'Save',
                self.save_figure)
        a.setToolTip('Save the figure')

        self.buttons = {}

        # Add the x,y location widget at the right side of the toolbar
        # The stretch factor is 1 which means any resizing of the toolbar
        # will resize this label instead of the buttons.
        if self.coordinates:
            self.locLabel = QtGui.QLabel( "", self )
            self.locLabel.setAlignment(
                    QtCore.Qt.AlignRight | QtCore.Qt.AlignTop )
            self.locLabel.setSizePolicy(
                QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                  QtGui.QSizePolicy.Ignored))
            labelAction = self.addWidget(self.locLabel)
            labelAction.setVisible(True)

        # reference holder for subplots_adjust window
        self.adj_window = None

    def mouse_move(self, event):
        #print 'mouse_move', event.button

        if not event.inaxes or not self._active:
            if self._lastCursor != mplCursors.POINTER:
                self.set_cursor(mplCursors.POINTER)
                self._lastCursor = mplCursors.POINTER
        else:
            if self._active=='ZOOM':
                if self._lastCursor != mplCursors.SELECT_REGION:
                    self.set_cursor(mplCursors.SELECT_REGION)
                    self._lastCursor = mplCursors.SELECT_REGION
                if self._xypress:
                    x, y = event.x, event.y
                    lastx, lasty, a, ind, lim, trans = self._xypress[0]
                    self.draw_rubberband(event, x, y, lastx, lasty)
            elif (self._active=='PAN' and
                  self._lastCursor != mplCursors.MOVE):
                self.set_cursor(mplCursors.MOVE)

                self._lastCursor = mplCursors.MOVE
            elif self._active=='SELECT':
                if self._lastCursor != mplCursors.SELECT_POINT:
                    QtGui.QApplication.restoreOverrideCursor()
                    QtGui.QApplication.setOverrideCursor(
                                            
QtGui.QCursor(mplCursors.SELECT_POINT))
                    self._lastCursor = mplCursors.SELECT_POINT

        if event.inaxes and event.inaxes.get_navigate():

            try: s = event.inaxes.format_coord(event.xdata, event.ydata)
            except ValueError: pass
            except OverflowError: pass
            else:
                if len(self.mode):
                    self.set_message('%s : %s' % (self.mode, s))
                else:
                    self.set_message(s)
        else: self.set_message(self.mode)

    def selectPointMode(self, *args):
        if self._active == 'SELECT':
            self._active = None
        else:
            self._active = 'SELECT'

        if self._idPress is not None:
            self._idPress = self.canvas.mpl_disconnect(self._idPress)
            self.mode = ''
        if self._idRelease is not None:
            self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
            self.mode = ''

        if self._active:

            self._idRelease = self.canvas.mpl_connect(
                'button_press_event', self.selectPoint)
            self.mode = 'pixel select mode'
            self.canvas.widgetlock(self)
        else:
            self.canvas.widgetlock.release(self)

        self.set_message(self.mode)

    def selectPoint(self, event):
        if event.inaxes and event.inaxes.get_navigate():
            self.xdatastart=event.xdata
            self.ydatastart=event.ydata
            self.xstart=event.x
            self.ystart=event.y
            self._banddraw = self.canvas.mpl_connect(
                'motion_notify_event',self.drawband)
            self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
            self._idRelease = self.canvas.mpl_connect(
                'button_release_event', self.selectSecondPoint)

    def selectSecondPoint(self, event):
        if event.inaxes and event.inaxes.get_navigate():
            self._banddraw=self.canvas.mpl_disconnect(self._banddraw)
            self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
            self._idRelease = self.canvas.mpl_connect(
                'button_press_event', self.selectPoint)
            self.draw_rubberband(event, 0, 0, 0, 0)
            self.emit(
                QtCore.SIGNAL('pickEvent'),
                self.xdatastart,
                self.ydatastart,
                event.xdata,
                event.ydata
            )

    def drawband(self, event):
        self.draw_rubberband(event,self.xstart, self.ystart, event.x, event.y)


The mouse release calls selectSecondPoint, which emits a signal containing the 
x and y start and end data. That gets routed to the onPick method on my 
Qt4Canvas instance:


    def onPick(self, xstart, ystart, xend, yend):
        xstart_i, ystart_i = self.getIndices(xstart, ystart)
        xend_i, yend_i = self.getIndices(xend, yend)

        if xstart_i > xend_i: xstart_i, xend_i = xend_i, xstart_i
        if ystart_i > yend_i: ystart_i, yend_i = yend_i, ystart_i

        try:
            indices = self.indices[ystart_i:yend_i+1, xstart_i:xend_i+1]
            self.emit(QtCore.SIGNAL('pickEvent'), indices.flatten())
        except TypeError:
            pass

which determines the indices of my data that are contained within the region 
defined by the user:

    def getIndices(self, xdata, ydata):
        xIndex = locateClosest(xdata, self.xPixelLocs)
        yIndex = locateClosest(ydata, self.yPixelLocs)
        return xIndex, yIndex

def locateClosest(point, points):
    compare = numpy.abs(points-point)
    return numpy.nonzero(numpy.ravel(compare==compare.min()))[0]



-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to