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 update_line_plots(self, x, y): xmin, xmax, ymin, ymax = self.im.get_extent() arr = self.im.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([y, x]) if any(np.isnan(point)): return i, j = point.astype(int) if 0 <= i < arr.shape[0]: self.plot_x_line(np.linspace(xmin, xmax, arr.shape[1]), arr[i, :]) if 0 <= j < arr.shape[1]: self.plot_y_line(np.linspace(ymin, ymax, arr.shape[0]), arr[:, j])
def convert_point(self,point_px, stop=False): ''' given a touch point in the view space, compute the corresponding point in data coords. assumes linear scaling! TODO: support log scaling there are basically two bbox transforms: 1) from figure coords to view coords, accounting for sign change in y. this then lets us compute axes box in view coords, and generate 2) transform from view to data coords. ''' transFig=BboxTransformTo(Bbox([(0,self.height),(self.width,0)])) bbox_axes=Bbox(transFig.transform(plt.gca().get_position())) bbox_data=Bbox([(self.xlim[0],self.ylim[0]),(self.xlim[1],self.ylim[1])]) transMPL=BboxTransform(bbox_axes,bbox_data) self.trans=transMPL ax_pt=transMPL.transform_point(point_px) return ax_pt
def get_courser_index(img, event): xmin, xmax, ymin, ymax = img.get_extent() if img.origin == 'upper': ymin, ymax = ymax, ymin arr = img.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) y, x = event.ydata, event.xdata point = trans.transform_point([y, x]) if any(np.isnan(point)): return None row, col = point.astype(int) # Clip the coordinates at array bounds return row, col
def convert_point(self, point_px, stop=False): ''' given a touch point in the view space, compute the corresponding point in data coords. assumes linear scaling! TODO: support log scaling there are basically two bbox transforms: 1) from figure coords to view coords, accounting for sign change in y. this then lets us compute axes box in view coords, and generate 2) transform from view to data coords. ''' transFig = BboxTransformTo(Bbox([(0, self.height), (self.width, 0)])) bbox_axes = Bbox(transFig.transform(plt.gca().get_position())) bbox_data = Bbox([(self.xlim[0], self.ylim[0]), (self.xlim[1], self.ylim[1])]) transMPL = BboxTransform(bbox_axes, bbox_data) self.trans = transMPL ax_pt = transMPL.transform_point(point_px) return ax_pt
def get_cursor_data(self, event): """Get the cursor data for a given event""" xmin, xmax, ymin, ymax = self.get_extent() if self.origin == 'upper': ymin, ymax = ymax, ymin arr = self.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) y, x = event.ydata, event.xdata i, j = trans.transform_point([y, x]).astype(int) # Clip the coordinates at array bounds if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): return None else: return arr[i, j]
def get_cursor_data(self, event): """Get the cursor data for a given event""" xmin, xmax, ymin, ymax = self.get_extent() if self.origin == "upper": ymin, ymax = ymax, ymin arr = self.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) y, x = event.ydata, event.xdata i, j = trans.transform_point([y, x]).astype(int) # Clip the coordinates at array bounds if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): return None else: return arr[i, j]
def get_cursor_data(self, event): """ Return the aggregated data at the event position or *None* if the event is outside the bounds of the current view. """ xmin, xmax, ymin, ymax = self.get_extent() if self.origin == "upper": ymin, ymax = ymax, ymin arr = self.get_ds_data().data data_extent = Bbox([[ymin, xmin], [ymax, xmax]]) array_extent = Bbox([[0, 0], arr.shape[:2]]) trans = BboxTransform(boxin=data_extent, boxout=array_extent) y, x = event.ydata, event.xdata i, j = trans.transform_point([y, x]).astype(int) # Clip the coordinates at array bounds if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): return None else: return arr[i, j]
def get_cursor_data(self, event): """Get the cursor data for a given event""" from matplotlib.transforms import Bbox, BboxTransform aximg = self.image xmin, xmax, ymin, ymax = aximg.get_extent() if aximg.origin == 'upper': ymin, ymax = ymax, ymin arr = aximg.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) y, x = event.ydata, event.xdata point = trans.transform_point([y, x]) if any(isnan(point)): return None i, j = point.astype(int) # Clip the coordinates at array bounds if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): return None else: return i, j, arr[i, j]
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
def update_image_data(self, x, y, update_line_plot=False): xmin, xmax, ymin, ymax = self.image.get_extent() arr = self.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([y, x]) if any(np.isnan(point)): return i, j = point.astype(int) if update_line_plot: if 0 <= i < arr.shape[0]: self.plot_x_line(np.linspace(xmin, xmax, arr.shape[1]), arr[i, :]) if 0 <= j < arr.shape[1]: self.plot_y_line(np.linspace(ymin, ymax, arr.shape[0]), arr[:, j]) # Clip the coordinates at array bounds if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]): return None else: return arr[i, j]