def __init__(self, image: AxesImage, new_pixel: Callable[[float, float], Tuple[float, float]], to_int: Callable[[float], int]): """ :param image: A reference to the image the cursor hovers over :param new_pixel: Callable to calculate the new position in data coordinates given an initial position. :param to_int: Callable converting a float to an integer. Used when converting from data coordinates to Qt screen-pixel coordinates with the origin at top-left of the widget In the case of small shifts it can matter if the coordinate is rounded up or down when moving in different directions as the new data coordinate may be calculate in the same pixel so to move away it must be rounded up. """ self.new_pixel = new_pixel self.to_int = to_int axes = image.axes self.data_to_display = axes.transData # compute pixel widths, assuming a regular grid self.extent = image.get_extent() xmin, xmax, ymin, ymax = self.extent if hasattr(image, 'orig_shape'): nx, ny = image.orig_shape else: arr = image.get_array() nx, ny = arr.shape[1], arr.shape[0] # y=rows, x=columns self.delta_x = (xmax - xmin) / nx self.delta_y = (ymax - ymin) / ny self.canvas = image.axes.figure.canvas
def update_fig(frame: int, im: AxesImage, stream: pyaudio.Stream) -> Tuple[AxesImage]: """ updates the image, just adds on samples at the start until the maximum size is reached, at which point it 'scrolls' horizontally by determining how much of the data needs to stay, shifting it left, and appending the new data. inputs: iteration number outputs: updated image """ data = get_sample(stream) arr_2d, freqs, times = get_specgram(data) im_data = im.get_array() # frame cannot be relied upon: we're called multiple times with 0 before it # starts to increment. frame = im_data.shape[1] // len(times) if frame < SAMPLES_PER_FRAME: im_data = np.hstack((im_data, arr_2d)) im.set_array(im_data) else: im_data = np.hstack(( im_data[:, len(times):], arr_2d, )) im.set_array(im_data) return im,
def cursor_info(image: AxesImage, xdata: float, ydata: float, full_bbox: Bbox = None) -> Optional[CursorInfo]: """Return information on the image for the given position in data coordinates. :param image: An instance of an image type :param xdata: X data coordinate of cursor :param xdata: Y data coordinate of cursor :param full_bbox: Bbox of full workspace dimension to use for transforming mouse position :return: None if point is not valid on the image else return CursorInfo type """ extent = image.get_extent() xmin, xmax, ymin, ymax = extent arr = image.get_array() data_extent = Bbox([[ymin, xmin], [ymax, xmax]]) array_extent = Bbox([[0, 0], arr.shape[:2]]) if full_bbox is None: trans = BboxTransform(boxin=data_extent, boxout=array_extent) else: # If the view is zoomed in and the slice is changed, then the image extents # and data extents change. This causes the cursor to be transformed to the # wrong point for certain MDH workspaces (since it cannot be dynamically rebinned). # This will use the full WS data dimensions to do the transformation trans = BboxTransform(boxin=full_bbox, boxout=array_extent) point = trans.transform_point([ydata, xdata]) if any(np.isnan(point)): return None point = point.astype(int) if 0 <= point[0] < arr.shape[0] and 0 <= point[1] < arr.shape[1]: return CursorInfo(array=arr, extent=extent, point=point) else: return None
def cursor_info(image: AxesImage, xdata: float, ydata: float) -> Optional[CursorInfo]: """Return information on the image for the given position in data coordinates. :param image: An instance of an image type :param xdata: X data coordinate of cursor :param xdata: Y data coordinate of cursor :return: None if point is not valid on the image else return CursorInfo type """ extent = image.get_extent() xmin, xmax, ymin, ymax = extent arr = image.get_array() data_extent = Bbox([[ymin, xmin], [ymax, xmax]]) array_extent = Bbox([[0, 0], arr.shape[:2]]) trans = BboxTransform(boxin=data_extent, boxout=array_extent) point = trans.transform_point([ydata, xdata]) if any(np.isnan(point)): return None point = point.astype(int) if 0 <= point[0] < arr.shape[0] and 0 <= point[1] < arr.shape[1]: return CursorInfo(array=arr, extent=extent, point=point) else: return None