Beispiel #1
0
 def update_annot(roiFile: pwsdt.RoiFile, poly: PathPatch):
     self.annot.xy = poly.get_path().vertices.mean(axis=0)  # Set the location to the center of the polygon.
     text = f"{roiFile.name}, {roiFile.number}"
     if self.metadata.pws:  # A day may come where fluorescence is not taken on the same camera as pws, in this case we will have multiple pixel sizes and ROI handling will need an update. for now just assume we'll use PWS pixel size
         if self.metadata.pws.pixelSizeUm:  # For some systems (NC) this is None
             text += f"\n{self.metadata.pws.pixelSizeUm ** 2 * np.sum(roiFile.getRoi().mask):.2f} $μm^2$"
     self.annot.set_text(text)
     self.annot.get_bbox_patch().set_alpha(0.4)
Beispiel #2
0
class VerticalMarker(QObject):

    moved = Signal(float)

    def __init__(self, canvas, x, color):
        super(VerticalMarker, self).__init__()
        self.x = x
        self.ax = canvas.figure.get_axes()[0]
        y0, y1 = self.ax.get_ylim()
        path = Path([(x, y0), (x, y1)], [Path.MOVETO, Path.LINETO])
        self.patch = PathPatch(path,
                               facecolor='None',
                               edgecolor=color,
                               picker=5,
                               linewidth=2.0,
                               animated=True)
        self.ax.add_patch(self.patch)
        self.is_moving = False

    def remove(self):
        self.patch.remove()

    def redraw(self):
        y0, y1 = self.ax.get_ylim()
        vertices = self.patch.get_path().vertices
        vertices[0] = self.x, y0
        vertices[1] = self.x, y1
        self.ax.draw_artist(self.patch)

    def get_x_in_pixels(self):
        x_pixels, _ = self.patch.get_transform().transform((self.x, 0))
        return x_pixels

    def is_above(self, x):
        return np.abs(self.get_x_in_pixels() - x) < 3

    def on_click(self, x):
        if self.is_above(x):
            self.is_moving = True

    def stop(self):
        self.is_moving = False

    def mouse_move(self, xd):
        if self.is_moving and xd is not None:
            self.x = xd
            self.moved.emit(xd)

    def should_override_cursor(self, x):
        return self.is_moving or self.is_above(x)
Beispiel #3
0
class VerticalMarker(QObject):
    """
    An interactive marker displayed as a vertical line.
    """

    x_moved = Signal(float)

    def __init__(self,
                 canvas,
                 color,
                 x,
                 y0=None,
                 y1=None,
                 line_width=1.0,
                 picker_width=5,
                 line_style='-'):
        """
        Init the marker.
        :param canvas: A MPL canvas.
        :param color: An MPL colour value
        :param x: The x coordinate (data) of the marker.
        :param y0: The y coordinate (data) of the bottom end of the marker. Default is None which means dynamically
            set it to the current lowest y value displayed.
        :param y1: The y coordinate (data) of the top end of the marker. Default is None which means dynamically
            set it to the current highest y value displayed.
        :param line_width: The line width (pixels).
        :param picker_width: The picker sensitivity (pixels).
        :param line_style: An MPL line style value.
        """
        super(VerticalMarker, self).__init__()
        self.ax = canvas.figure.get_axes()[0]
        self.x = x
        self.y0 = y0
        self.y1 = y1
        y0, y1 = self._get_y0_y1()
        path = Path([(x, y0), (x, y1)], [Path.MOVETO, Path.LINETO])
        self.patch = PathPatch(path,
                               facecolor='None',
                               edgecolor=color,
                               picker=picker_width,
                               linewidth=line_width,
                               linestyle=line_style,
                               animated=True)
        self.ax.add_patch(self.patch)
        self.is_moving = False

    def _get_y0_y1(self):
        """
        Calculate the current y coordinates of the line ends.
        :return: Tuple y0, y1.
        """
        if self.y0 is None or self.y1 is None:
            y0, y1 = self.ax.get_ylim()
        if self.y0 is not None:
            y0 = self.y0
        if self.y1 is not None:
            y1 = self.y1
        return y0, y1

    def remove(self):
        """
        Remove this marker from the canvas.
        """
        self.patch.remove()

    def redraw(self):
        """
        Redraw this marker.
        """
        y0, y1 = self._get_y0_y1()
        vertices = self.patch.get_path().vertices
        vertices[0] = self.x, y0
        vertices[1] = self.x, y1
        self.ax.draw_artist(self.patch)

    def get_x_in_pixels(self):
        """
        Get the x coordinate in screen pixels.
        """
        x_pixels, _ = self.patch.get_transform().transform((self.x, 0))
        return x_pixels

    def is_above(self, x, y):
        """
        Check if a mouse positioned at (x, y) is over this marker.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True or False.
        """
        x_pixels, y_pixels = self.patch.get_transform().transform((x, y))
        if self.y0 is not None and y < self.y0:
            return False
        if self.y1 is not None and y > self.y1:
            return False
        return abs(self.get_x_in_pixels() - x_pixels) < 3

    def mouse_move_start(self, x, y):
        """
        Start moving this marker if (x, y) is above it. Ignore otherwise.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        """
        self.is_moving = self.is_above(x, y)

    def mouse_move_stop(self):
        """
        Stop moving.
        """
        self.is_moving = False

    def mouse_move(self, x, y=None):
        """
        Move this marker to a new position if movement had been started earlier by a call to mouse_move_start(x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True if moved or False if stayed at the old position.
        """
        if self.is_moving and x is not None:
            self.x = x
            self.x_moved.emit(x)
            return True
        return False

    def get_cursor_at_y(self, y):
        """
        Get an override cursor for an y coordinate given that the x == self.x
        :param y: A y coordinate.
        :return: QCursor or None.
        """
        return QCursor(Qt.SizeHorCursor)

    def override_cursor(self, x, y):
        """
        Get the override cursor for mouse position (x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: QCursor or None.
        """
        if self.y0 is not None and y < self.y0:
            return None
        if self.y1 is not None and y > self.y1:
            return None
        if self.is_moving or self.is_above(x, y):
            return self.get_cursor_at_y(y)
        return None
Beispiel #4
0
class HorizontalMarker(QObject):
    """
    An interactive marker displayed as a horizontal line.
    """

    y_moved = Signal(float)

    def __init__(self,
                 canvas,
                 color,
                 y,
                 x0=None,
                 x1=None,
                 line_width=1.0,
                 picker_width=5,
                 line_style='-',
                 move_cursor=None,
                 axis=None):
        """
        Init the marker.
        :param canvas: A MPL canvas.
        :param color: An MPL colour value
        :param y: The y coordinate (data) of the marker.
        :param x0: The x coordinate (data) of the left end of the marker. Default is None which means dynamically
            set it to the current maximum x value displayed.
        :param x1: The x coordinate (data) of the right end of the marker. Default is None which means dynamically
            set it to the current minimum x value displayed.
        :param line_width: The line width (pixels).
        :param picker_width: The picker sensitivity (pixels).
        :param line_style: An MPL line style value.
        """
        super(HorizontalMarker, self).__init__()
        self.canvas = canvas
        if axis is None:
            self.axis = canvas.figure.get_axes()[0]
        else:
            self.axis = axis
        self.y = y
        self.x0 = x0
        self.x1 = x1
        x0, x1 = self._get_x0_x1()
        path = Path([(x0, y), (x1, y)], [Path.MOVETO, Path.LINETO])
        self.patch = PathPatch(path,
                               facecolor='None',
                               edgecolor=color,
                               picker=picker_width,
                               linewidth=line_width,
                               linestyle=line_style,
                               animated=True)
        self.axis.add_patch(self.patch)
        self.axis.interactive_markers.append(self.patch)
        self.is_moving = False
        self.move_cursor = move_cursor

    def _get_x0_x1(self):
        """
        Calculate the current x coordinates of the line ends.
        :return: Tuple x0, x1.
        """
        if self.x0 is None or self.x1 is None:
            x0, x1 = self.axis.get_xlim()
        if self.x0 is not None:
            x0 = self.x0
        if self.x1 is not None:
            x1 = self.x1
        return x0, x1

    def remove(self):
        """
        Remove this marker from the canvas.
        """
        self.patch.remove()

    def redraw(self):
        """
        Redraw this marker.
        """
        x0, x1 = self._get_x0_x1()
        vertices = self.patch.get_path().vertices
        vertices[0] = x0, self.y
        vertices[1] = x1, self.y
        self.axis.draw_artist(self.patch)

    def set_visible(self, visible):
        self.patch.set_visible(visible)

    def set_color(self, color):
        """
        Set the colour of the marker
        :param color: The color to set the marker to.
        """
        self.patch.set_edgecolor(color)

    def get_position(self):
        """
        Get the y coordinate in axes coords.
        :return: y in axes coords
        """
        return self.y

    def set_position(self, y):
        """
        Set the y position of the marker.
        :param y: An y axis coordinate.
        """
        self.y = y
        self.y_moved.emit(y)

    def get_y_in_pixels(self):
        """
        Returns the y coordinate in screen pixels.
        :return: y in pixels
        """
        _, y_pixels = self.patch.get_transform().transform((0, self.y))
        return y_pixels

    def is_above(self, x, y):
        """
        Check if a mouse positioned at (x, y) is over this marker.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True or False.
        """
        _, y_pixels = self.patch.get_transform().transform((x, y))

        if self.x0 is not None and x < self.x0:
            return False
        if self.x1 is not None and x > self.x1:
            return False
        return abs(self.get_y_in_pixels() - y_pixels) < MARKER_SENSITIVITY

    def mouse_move_start(self, x, y):
        """
        Start moving this marker if (x, y) is above it. Ignore otherwise.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :param pixels: True if the coordinates are already in pixels.
        """
        self.is_moving = self.is_above(x, y)

    def mouse_move_stop(self):
        """
        Stop moving.
        """
        self.is_moving = False

    def mouse_move(self, x, y):
        """
        Move this marker to a new position if movement had been started earlier by a call to mouse_move_start(x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True if moved or False if stayed at the old position.
        """
        if self.is_moving and y is not None and x is not None:
            self.set_position(y)
            return True
        return False

    def is_marker_moving(self):
        """
        Returns true if the marker is being moved
        :return: True if the marker is being moved.
        """
        return self.is_moving

    def override_cursor(self, x, y):
        """
        Get the override cursor for mouse position (x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: QCursor or None.
        """
        if self.x0 is not None and x < self.x0:
            return None
        if self.x1 is not None and x > self.x1:
            return None
        if self.is_moving or self.is_above(x, y):
            return self.move_cursor if self.move_cursor is not None else QCursor(
                Qt.SizeVerCursor)
        return None

    def set_move_cursor(self, cursor, x_pos, y_pos):
        """Set the style of the cursor to use when the marker is moving"""
        if cursor is not None:
            cursor = QCursor(cursor)
        self.move_cursor = cursor
        self.override_cursor(x_pos, y_pos)
Beispiel #5
0
class VerticalMarker(QObject):
    """
    An interactive marker displayed as a vertical line.
    """

    x_moved = Signal(float)

    def __init__(self, canvas, color, x, y0=None, y1=None, line_width=1.0, picker_width=5, line_style='-'):
        """
        Init the marker.
        :param canvas: A MPL canvas.
        :param color: An MPL colour value
        :param x: The x coordinate (data) of the marker.
        :param y0: The y coordinate (data) of the bottom end of the marker. Default is None which means dynamically
            set it to the current lowest y value displayed.
        :param y1: The y coordinate (data) of the top end of the marker. Default is None which means dynamically
            set it to the current highest y value displayed.
        :param line_width: The line width (pixels).
        :param picker_width: The picker sensitivity (pixels).
        :param line_style: An MPL line style value.
        """
        super(VerticalMarker, self).__init__()
        self.ax = canvas.figure.get_axes()[0]
        self.x = x
        self.y0 = y0
        self.y1 = y1
        y0, y1 = self._get_y0_y1()
        path = Path([(x, y0), (x, y1)], [Path.MOVETO, Path.LINETO])
        self.patch = PathPatch(path, facecolor='None', edgecolor=color, picker=picker_width,
                               linewidth=line_width, linestyle=line_style, animated=True)
        self.ax.add_patch(self.patch)
        self.is_moving = False

    def _get_y0_y1(self):
        """
        Calculate the current y coordinates of the line ends.
        :return: Tuple y0, y1.
        """
        if self.y0 is None or self.y1 is None:
            y0, y1 = self.ax.get_ylim()
        if self.y0 is not None:
            y0 = self.y0
        if self.y1 is not None:
            y1 = self.y1
        return y0, y1

    def remove(self):
        """
        Remove this marker from the canvas.
        """
        self.patch.remove()

    def redraw(self):
        """
        Redraw this marker.
        """
        y0, y1 = self._get_y0_y1()
        vertices = self.patch.get_path().vertices
        vertices[0] = self.x, y0
        vertices[1] = self.x, y1
        self.ax.draw_artist(self.patch)

    def get_x_in_pixels(self):
        """
        Get the x coordinate in screen pixels.
        """
        x_pixels, _ = self.patch.get_transform().transform((self.x, 0))
        return x_pixels

    def is_above(self, x, y):
        """
        Check if a mouse positioned at (x, y) is over this marker.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True or False.
        """
        x_pixels, y_pixels = self.patch.get_transform().transform((x, y))
        if self.y0 is not None and y < self.y0:
            return False
        if self.y1 is not None and y > self.y1:
            return False
        return abs(self.get_x_in_pixels() - x_pixels) < 3

    def mouse_move_start(self, x, y):
        """
        Start moving this marker if (x, y) is above it. Ignore otherwise.
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        """
        self.is_moving = self.is_above(x, y)

    def mouse_move_stop(self):
        """
        Stop moving.
        """
        self.is_moving = False

    def mouse_move(self, x, y=None):
        """
        Move this marker to a new position if movement had been started earlier by a call to mouse_move_start(x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: True if moved or False if stayed at the old position.
        """
        if self.is_moving and x is not None:
            self.x = x
            self.x_moved.emit(x)
            return True
        return False

    def get_cursor_at_y(self, y):
        """
        Get an override cursor for an y coordinate given that the x == self.x
        :param y: A y coordinate.
        :return: QCursor or None.
        """
        return QCursor(Qt.SizeHorCursor)

    def override_cursor(self, x, y):
        """
        Get the override cursor for mouse position (x, y)
        :param x: An x mouse coordinate.
        :param y: An y mouse coordinate.
        :return: QCursor or None.
        """
        if self.y0 is not None and y < self.y0:
            return None
        if self.y1 is not None and y > self.y1:
            return None
        if self.is_moving or self.is_above(x, y):
            return self.get_cursor_at_y(y)
        return None