Source code for continuousflex.viewers.nma_gui.matplotlib_point_selector

# **************************************************************************
# *
# * Authors:     J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
# *
# * Unidad de  Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************

from continuousflex.viewers.nma_plotter import plotArray2D_xy


[docs]class PointSelector(): """ Graphical manager based on Matplotlib to handle mouse events of click, drag and release and mark some point from input Data as 'selected'. """ def __init__(self, ax, data, callback=None, LimitL=None, LimitH=None): self.ax = ax self.data = data self.LimitL = LimitL self.LimitH = LimitH self.createPlots(ax) self.press = None self.callback = callback # connect to all the events we need self.cidpress = self.rectangle_selection.figure.canvas.mpl_connect( 'button_press_event', self.onPress) self.cidrelease = self.rectangle_selection.figure.canvas.mpl_connect( 'button_release_event', self.onRelease) self.cidmotion = self.rectangle_selection.figure.canvas.mpl_connect( 'motion_notify_event', self.onMotion)
[docs] def createPlots(self, ax): # plotArray2D(ax, self.data) if(self.LimitL): plotArray2D_xy(ax, self.data, vvmin=self.LimitL, vvmax=self.LimitH) else: plotArray2D_xy(ax, self.data) self.createSelectionPlot(ax)
[docs] def getSelectedData(self): xs, ys = [], [] for point in self.data: if point.getState() == 1: # point selected xs.append(point.getX()) ys.append(point.getY()) return xs, ys
[docs] def createSelectionPlot(self, ax): xs, ys = self.getSelectedData() self.plot_selected, = ax.plot(xs, ys, 'o', ms=8, alpha=0.4, color='yellow') self.rectangle_selection, = ax.plot([0], [0], ':') # empty line
[docs] def onPress(self, event): if event.inaxes != self.rectangle_selection.axes: return # ignore click event if toolbar is active if self.ax.get_navigate_mode(): return self.press = True self.originX = event.xdata self.originY = event.ydata
[docs] def onMotion(self, event): if self.press is None: return self.update(event, addSelected=False)
[docs] def onRelease(self, event): self.press = None self.update(event, addSelected=True)
[docs] def inside(self, x, y, xmin, xmax, ymin, ymax): return (xmin <= x <= xmax and ymin <= y <= ymax)
[docs] def update(self, event, addSelected=False): """ Update the plots with selected points. Take the selection rectangle and include points from 'event'. If addSelected is True, update the data selection. """ # ignore click event if toolbar is active if self.ax.get_navigate_mode(): return ox, oy = self.originX, self.originY ex, ey = event.xdata, event.ydata xs1, ys1 = self.getSelectedData() x1 = min(ox, ex) x2 = max(ox, ex) y1 = min(oy, ey) y2 = max(oy, ey) if addSelected: xs, ys = [0], [0] # rectangle selection else: xs = [x1, x2, x2, x1, x1] ys = [y1, y1, y2, y2, y1] for point in self.data: x, y = point.getX(), point.getY() if self.inside(x, y, x1, x2, y1, y2): xs1.append(x) ys1.append(y) if addSelected: point.setSelected() if self.callback: # Notify changes on selection self.callback() self.plot_selected.set_data(xs1, ys1) self.rectangle_selection.set_data(xs, ys) self.ax.figure.canvas.draw()