Beispiel #1
0
class PeakSelector(_SelectorWidget):
    """Draw a Peak as triangle."""

    # pylint: disable=too-many-arguments
    # pylint: disable=too-many-instance-attributes
    # pylint: disable=invalid-name
    # pylint: disable=attribute-defined-outside-init
    def __init__(self,
                 ax,
                 onselect,
                 minfwhm=None,
                 minamp=None,
                 useblit=False,
                 wedgeprops=None,
                 onmove_callback=None,
                 peak_stays=False,
                 button=None,
                 limits=None):
        _SelectorWidget.__init__(self,
                                 ax,
                                 onselect,
                                 useblit=useblit,
                                 button=button)

        if minfwhm is not None or minamp is not None:
            raise NotImplementedError

        if wedgeprops is None:
            wedgeprops = dict(facecolor='red', alpha=0.5, fill=True)

        wedgeprops['animated'] = self.useblit

        self.wedge = None
        self.pressv = None

        if limits is None:
            limits = (-np.inf, np.inf)
        self.limits = limits

        self.wedgeprops = wedgeprops
        self.onmove_callback = onmove_callback
        self.minfwhm = minfwhm
        self.minamp = minamp
        self.peak_stays = peak_stays

        # Needed when dragging out of axes
        self.prev = (0, 0)

        # Reset canvas so that `new_axes` connects events.
        self.canvas = None
        self.new_axes(ax)

    def new_axes(self, ax):
        """Set SpanSelector to operate on a new Axes"""
        self.ax = ax
        if self.canvas is not ax.figure.canvas:
            if self.canvas is not None:
                self.disconnect_events()

            self.canvas = ax.figure.canvas
            self.connect_default_events()

        self.wedge = Wedge((0, 0),
                           1e10,
                           0,
                           0,
                           visible=False,
                           **self.wedgeprops)
        if self.peak_stays:
            self.stay_wedge = Wedge((0, 0),
                                    1e10,
                                    0,
                                    0,
                                    visible=False,
                                    **self.wedgeprops)
            self.stay_wedge.set_animated(False)
            self.ax.add_patch(self.stay_wedge)

        self.ax.add_patch(self.wedge)
        self.artists = [self.wedge]

    def set_wedgeprops(self, wedgeprops):
        """Custom: set new rectprops."""
        self.wedgeprops = wedgeprops
        self.new_axes(self.ax)

    def set_limits(self, limits):
        """Sets new limits. Peak will only be drawn when press event occurs
        inside these x values."""
        self.limits = limits

    def ignore(self, event):
        """return *True* if *event* should be ignored"""
        return _SelectorWidget.ignore(self, event) or not self.visible

    def _press(self, event):
        """on button press event"""
        x0, y0 = self._get_data(event)
        if not self.limits[0] <= x0 <= self.limits[1]:
            return True
        self.wedge.set_visible(self.visible)
        if self.peak_stays:
            self.stay_wedge.set_visible(False)
            # really force a draw so that the stay rect is not in
            # the blit background
            if self.useblit:
                self.canvas.draw()
        self.pressv = (x0, y0)
        self.wedge.set_center((x0, y0))
        return False

    def _release(self, event):
        """on button release event"""
        if self.pressv is None:
            return True
        self.buttonDown = False

        self.wedge.set_visible(False)

        if self.peak_stays:
            self.stay_wedge.set_center(self.wedge.center)
            self.stay_wedge.set_radius(self.wedge.r)
            self.stay_wedge.set_theta1(self.wedge.theta1)
            self.stay_wedge.set_theta2(self.wedge.theta2)
            self.stay_wedge.set_visible(True)

        self.canvas.draw_idle()

        x0, y0, = self.pressv
        center = x0
        amplitude = y0

        x, y = self._get_data(event)
        angle = abs(np.arctan((x - x0) / (y - y0)))

        self.onselect(center, amplitude, angle)
        self.pressv = None
        return False

    def _onmove(self, event):
        """on motion notify event"""
        if self.pressv is None:
            return True
        x, y = self._get_data(event)
        if x is None:
            return True
        x0, y0, = self.pressv

        angle = abs(np.arctan((x - x0) / (y - y0)))
        self.wedge.set_theta1(np.rad2deg(-angle) - 90)
        self.wedge.set_theta2(np.rad2deg(angle) - 90)

        if self.onmove_callback is not None:
            center = x0
            amplitude = y0
            self.onmove_callback(center, amplitude, angle)

        self.update()
        return False