def limit_rect(self, args): if isinstance(args, tuple): rect = Rect(*args) elif args is None: rect = Rect(-np.inf, -np.inf, np.inf, np.inf) else: rect = Rect(args) if self._limit_rect != rect: self._limit_rect = rect
def test_update_camera_position_component_marking(self, base_settings, image_view, pos): roi = np.zeros(base_settings.image.get_channel(0).shape, dtype=np.uint8) roi[..., 2:-2, 2:-2, 2:-2] = 1 base_settings.roi = roi image_view.viewer.dims.set_point(1, 0) rect = Rect(image_view.viewer_widget.view.camera.get_state()["rect"]) rect.pos = pos rect.size = (100, 100) image_view.viewer_widget.view.camera.set_state({"rect": rect}) image_view.component_mark(1, False) assert image_view.viewer.dims.point[1] != 0 assert image_view.viewer_widget.view.camera.get_state( )["rect"].pos != pos
def set_state(self, state=None, **kwargs): D = state or {} if 'rect' not in D: return for cam in self._linked_cameras: r = Rect(D['rect']) if cam is self._linked_cameras_no_update: continue try: cam._linked_cameras_no_update = self cam_rect = cam.get_state()['rect'] r.top = cam_rect.top r.bottom = cam_rect.bottom cam.set_state({'rect': r}) finally: cam._linked_cameras_no_update = None
def fit_view(self, rect=None): # Lock updates in other threads self.shape_collection.lock_updates() if not rect: rect = Rect(0, 0, 10, 10) try: rect.left, rect.right = self.shape_collection.bounds(axis=0) rect.bottom, rect.top = self.shape_collection.bounds(axis=1) except TypeError: pass self.vispy_canvas.view.camera.rect = rect self.shape_collection.unlock_updates()
def __init__(self, **kwargs): super(RadolanCanvas, self).__init__(keys='interactive', **kwargs) # set size ov Canvas self.size = 450, 450 # unfreeze needed to add more elements self.unfreeze() # add grid central widget self.grid = self.central_widget.add_grid() # add view to grid self.view = self.grid.add_view(row=0, col=0) self.view.border_color = (0.5, 0.5, 0.5, 1) # add signal emitters self.mouse_moved = EventEmitter(source=self, type="mouse_moved") # block double clicks self.events.mouse_double_click.block() # initialize empty RADOLAN image img_data = np.zeros((900, 900)) # initialize colormap, we take cubehelix for now # this is the most nice colormap for radar in vispy cmap = 'cubehelix' # initialize Image Visual with img_data # add to view self.image = Image( img_data, method='subdivide', #interpolation='bicubic', cmap=cmap, parent=self.view.scene) # add transform to Image # (mostly positioning within canvas) self.image.transform = STTransform(translate=(0, 0, 0)) # get radolan ll point coodinate into self.r0 self.r0 = utils.get_radolan_origin() # create cities (Markers and Text Visuals self.create_cities() # create PanZoomCamera self.cam = PanZoomCamera(name="PanZoom", rect=Rect(0, 0, 900, 900), aspect=1, parent=self.view.scene) self.view.camera = self.cam self._mouse_position = None self.freeze() # print FPS to console, vispy SceneCanvas internal function self.measure_fps()
def set_state(self, state=None, **kwargs): D = state or {} if 'rect' not in D: return for cam in self._linked_cameras: r = Rect(D['rect']) if cam is self._linked_cameras_no_update: continue try: cam._linked_cameras_no_update = self cam_rect = cam.get_state()['rect'] r.top = cam_rect.top r.bottom = cam_rect.bottom cam.set_state({'rect':r}) finally: cam._linked_cameras_no_update = None
def __init__(self, texdata, parent, overlay=False): self._parent2 = parent self.overlay = overlay #just set a dummy value self._shape = (10.0, 22500) self.tex = gloo.Texture2D(texdata, format='luminance', internalformat='r32f', interpolation="linear") self.get_data = visuals.shaders.Function(norm_luminance) self.get_data['vmin'] = -80 self.get_data['vmax'] = -40 self.get_data['texture'] = self.tex self.bb = Rect((0, 0, 1, 1)) scene.Image.__init__(self, method='subdivide', grid=(1000, 1), parent=parent) #set in the main program self.shared_program.frag['get_data'] = self.get_data #needs no external color map if self.overlay == "r": self.set_gl_state('additive') self.shared_program.frag[ 'color_transform'] = visuals.shaders.Function(r_cmap) elif self.overlay == "g": self.set_gl_state('additive') self.shared_program.frag[ 'color_transform'] = visuals.shaders.Function(g_cmap)
def on_resize(self, event): vp = (0, 0, self.physical_size[0], self.physical_size[1]) self.context.set_viewport(*vp) for line in self.lines: line.transforms.configure(canvas=self, viewport=vp) # Need to update clipping boundaries if the window resizes. tr = self.lines[1].transforms.get_transform('visual', 'framebuffer') self.clipper.bounds = tr.map(Rect(100, -20, 200, 40))
def on_resize(self, event): for line in self.lines: # let the transform systems know that the window has resized line.tr_sys.auto_configure() # Need to update clipping boundaries if the window resizes. trs = self.lines[1].tr_sys tr = trs.document_to_framebuffer * trs.visual_to_document self.clipper.bounds = tr.map(Rect(50, -15, 250, 30))
def _set_all_x_axes(self, xaxis): if xaxis is not None: left, right = xaxis for pw in self.plot_widgets: if pw.linked: rect = Rect(pw.view.camera.rect) rect.left = left rect.right = right pw.view.camera.rect = rect else: for c in pw.view.scene.children: if isinstance(c, Histogram) and pw.data is not None: t, data, bins, orientation = pw.data subset = np.where((t >= left) & (t <= left + right)) (rr, tris) = _do_the_histogramming( data[subset], bins, orientation) c.set_data(rr, tris, color=c.color)
def _set_all_x_axes(self, xaxis): if xaxis is not None: left, right = xaxis for pw in self.plot_widgets: if pw.linked: rect = Rect(pw.view.camera.rect) rect.left = left rect.right = right pw.view.camera.rect = rect else: for c in pw.view.scene.children: if isinstance(c, Histogram) and pw.data is not None: t, data, bins, orientation = pw.data subset = np.where((t >= left) & (t <= left + right)) (rr, tris) = _do_the_histogramming(data[subset], bins, orientation) c.set_data(rr, tris, color=c.color)
def _update_child_widget_dim(self): # think in terms of (x, y). (row, col) makes code harder to read ymax, xmax = self.grid_size if ymax <= 0 or xmax <= 0: return rect = self.rect # .padded(self.padding + self.margin) if rect.width <= 0 or rect.height <= 0: return if self._need_solver_recreate: self._need_solver_recreate = False self._recreate_solver() # we only need to remove and add the height and width constraints of # the solver if they are not the same as the current value if rect.height != self._var_h.value: if self._height_stay: self._solver.remove_constraint(self._height_stay) self._var_h.value = rect.height self._height_stay = self._solver.add_stay(self._var_h, strength=STRONG) if rect.width != self._var_w.value: if self._width_stay: self._solver.remove_constraint(self._width_stay) self._var_w.value = rect.width self._width_stay = self._solver.add_stay(self._var_w, strength=STRONG) value_vectorized = np.vectorize(lambda x: x.value) for (_, val) in self._grid_widgets.items(): (row, col, rspan, cspan, widget) = val width = np.sum(value_vectorized( self._width_grid[row][col:col+cspan])) height = np.sum(value_vectorized( self._height_grid[col][row:row+rspan])) if col == 0: x = 0 else: x = np.sum(value_vectorized(self._width_grid[row][0:col])) if row == 0: y = 0 else: y = np.sum(value_vectorized(self._height_grid[col][0:row])) if isinstance(widget, ViewBox): widget.rect = Rect(x, y, width, height) else: widget.size = (width, height) widget.pos = (x, y)
def __init__(self, **kwargs): super(DXCanvas, self).__init__(keys='interactive', **kwargs) self.size = 450, 450 self.unfreeze() # add grid central widget self.grid = self.central_widget.add_grid() # add view to grid self.view = self.grid.add_view(row=0, col=0) self.view.border_color = (0.5, 0.5, 0.5, 1) # This is hardcoded now, but maybe handled as the data source changes self.img_data = np.zeros((360, 128)) # initialize colormap, we take cubehelix for now # this is the most nice colormap for radar in vispy cmap = 'cubehelix' # this way we can hold several images on the same scene # usable for radar mosaic self.images = [] self.image = PolarImage( source=None, data=self.img_data, method='impostor', # interpolation='bicubic', cmap=cmap, clim=(-32.5, 95), parent=self.view.scene) self.images.append(self.image) # add signal emitters self.mouse_moved = EventEmitter(source=self, type="mouse_moved") self.key_pressed = EventEmitter(source=self, type="key_pressed") # block double clicks self.events.mouse_double_click.block() # create PanZoomCamera # the camera should zoom to the ppi "bounding box" self.cam = PanZoomCamera(name="PanZoom", rect=Rect(0, 0, 256, 256), aspect=1, parent=self.view.scene) self.view.camera = self.cam self._mouse_position = None self.freeze() self.measure_fps()
def zoom(self, factor, center=None): # Init some variables center = center if (center is not None) else self.center assert len(center) in (2, 3, 4) # Get scale factor, take scale ratio into account if np.isscalar(factor): scale = [factor, factor] else: if len(factor) != 2: raise TypeError("factor must be scalar or length-2 sequence.") scale = list(factor) if self.aspect is not None: scale[0] = scale[1] # Make a new object (copy), so that allocation will # trigger view_changed: rect = Rect(self.rect) # Get space from given center to edges left_space = center[0] - rect.left right_space = rect.right - center[0] bottom_space = center[1] - rect.bottom top_space = rect.top - center[1] # Scale these spaces rect.left = center[0] - left_space * scale[0] rect.right = center[0] + right_space * scale[0] rect.bottom = center[1] - bottom_space * scale[1] rect.top = center[1] + top_space * scale[1] self.rect = rect self.currect_scale *= factor for text, font_size in zip(self.texts,self.font_sizes): text.font_size = font_size / self.currect_scale
def rect(self, args): if isinstance(args, tuple): rect = Rect(*args) else: rect = Rect(args) # THIS DOESN'T WORK. The `rect` object doesn't represent a fixed coordinate system # (0 and 1 have different meanings at different zoom levels) # Limit how far we can pan and zoom out # if self.parent.transform # if rect.left >= self._pan_limits[2]: # print("To far right") # return # elif rect.left <= self._pan_limits[0]: # print("To far left") # return # if self._pan_limits is not None: # new_left = np.clip(rect.left, self._pan_limits[0] - self._zoom_limits[0], self._pan_limits[2]) # new_right = np.clip(rect.right, self._pan_limits[0], self._pan_limits[2] + self._zoom_limits[0]) # new_bottom = np.clip(rect.bottom, self._pan_limits[1] - self._zoom_limits[0], self._pan_limits[3]) # new_top = np.clip(rect.top, self._pan_limits[1], self._pan_limits[3] + self._zoom_limits[1]) # else: # new_left = rect.left # new_right = rect.right # new_bottom = rect.bottom # new_top = rect.top # # # Limit how far we can zoom in # new_size_x = new_right - new_left # new_size_y = new_top - new_bottom # if self._zoom_limits is not None: # new_size_x = max(new_size_x, self._zoom_limits[0]) # new_size_y = max(new_size_y, self._zoom_limits[1]) # rect = Rect(new_left, new_bottom, new_size_x, new_size_y) if self._rect != rect: self._rect = rect self.view_changed()
def move_to(self, x=None, y=None, z=None, scale=1) -> Navigator: if z is not None: self.viewer.dims.set_point(0, z) with self.camera_state() as state: rect = state["rect"] size = (rect.width * scale, rect.height * scale) center = (default(x, rect.center[0]), default(y, rect.center[1])) pos = ( center[0] - size[0] / 2, center[1] - size[1] / 2, ) state["rect"] = Rect(pos, size) return self
def _update_child_widget_dim(self): # think in terms of (x, y). (row, col) makes code harder to read ymax, xmax = self.grid_size if ymax <= 0 or xmax <= 0: return rect = self.rect # .padded(self.padding + self.margin) if rect.width <= 0 or rect.height <= 0: return if self._need_solver_recreate: self._need_solver_recreate = False self._recreate_solver() # we only need to remove and add the height and width constraints of # the solver if they are not the same as the current value h_changed = abs(rect.height - self._var_h.value()) > 1e-4 w_changed = abs(rect.width - self._var_w.value()) > 1e-4 if h_changed: self._solver.suggestValue(self._var_h, rect.height) if w_changed: self._solver.suggestValue(self._var_w, rect.width) if h_changed or w_changed: self._solver.updateVariables() value_vectorized = np.vectorize(lambda x: x.value()) for (_, val) in self._grid_widgets.items(): (row, col, rspan, cspan, widget) = val width = np.sum( value_vectorized(self._width_grid[row][col:col + cspan])) height = np.sum( value_vectorized(self._height_grid[col][row:row + rspan])) if col == 0: x = 0 else: x = np.sum(value_vectorized(self._width_grid[row][0:col])) if row == 0: y = 0 else: y = np.sum(value_vectorized(self._height_grid[col][0:row])) if isinstance(widget, ViewBox): widget.rect = Rect(x, y, width, height) else: widget.size = (width, height) widget.pos = (x, y)
def move_by(self, x=0, y=0, z=0, scale=1) -> Navigator: if z: new_z = self.viewer.dims.point + z self.viewer.dims.set_point(new_z) with self.camera_state() as state: rect = state["rect"] size = (rect.width * scale, rect.height * scale) center = ( rect.center[0] + x, rect.center[1] + y, ) pos = ( center[0] - size[0] / 2, center[1] - size[1] / 2, ) state["rect"] = Rect(pos, size) return self
def _zoom(self): self._stop() if self.napari_viewer.dims.ndisplay != 2: show_info("Zoom in does not work in 3D mode") num = self.component_selector.value labels = self.labels_layer.value bound_info = self.roi_info.bound_info.get(num, None) if bound_info is None: return lower_bound = self._data_to_world(labels, bound_info.lower) upper_bound = self._data_to_world(labels, bound_info.upper) diff = upper_bound - lower_bound frame = diff * 0.2 if self.napari_viewer.dims.ndisplay == 2: rect = Rect(pos=(lower_bound - frame)[-2:][::-1], size=(diff + 2 * frame)[-2:][::-1]) self.napari_viewer.window.qt_viewer.view.camera.set_state({"rect": rect}) self._update_point(lower_bound, upper_bound)
def zoom(self, factor, center=None): """ Zoom in (or out) at the given center Parameters ---------- factor : float or tuple Fraction by which the scene should be zoomed (e.g. a factor of 2 causes the scene to appear twice as large). center : tuple of 2-4 elements The center of the view. If not given or None, use the current center. """ assert len(center) in (2, 3, 4) # Get scale factor, take scale ratio into account if np.isscalar(factor): scale = [factor, factor] else: if len(factor) != 2: raise TypeError("factor must be scalar or length-2 sequence.") scale = list(factor) if self.aspect is not None: scale[0] = scale[1] # Init some variables center = center if (center is not None) else self.center # Make a new object (copy), so that allocation will # trigger view_changed: rect = Rect(self.rect) # Get space from given center to edges left_space = center[0] - rect.left right_space = rect.right - center[0] bottom_space = center[1] - rect.bottom top_space = rect.top - center[1] # Scale these spaces rect.left = center[0] - left_space * scale[0] rect.right = center[0] + right_space * scale[0] rect.bottom = center[1] - bottom_space * scale[1] rect.top = center[1] + top_space * scale[1] self.limit_zoom(rect) self.rect = rect
def _shift_if_need(self, labels, bound_info): if self.napari_viewer.dims.ndisplay != 2: return lower_bound = self._data_to_world(labels, bound_info.lower) upper_bound = self._data_to_world(labels, bound_info.upper) self._update_point(lower_bound, upper_bound) l_bound = lower_bound[-2:][::-1] u_bound = upper_bound[-2:][::-1] rect = Rect(self.napari_viewer.window.qt_viewer.view.camera.get_state()["rect"]) if rect.contains(*l_bound) and rect.contains(*u_bound): return size = u_bound - l_bound rect.size = tuple(np.max([rect.size, size * 1.2], axis=0)) pos = rect.pos if rect.left > l_bound[0]: pos = l_bound[0], pos[1] if rect.right < u_bound[0]: pos = pos[0] + u_bound[0] - rect.right, pos[1] if rect.bottom > l_bound[1]: pos = pos[0], l_bound[1] if rect.top < u_bound[1]: pos = pos[0], pos[1] + (u_bound[1] - rect.top) rect.pos = pos self.napari_viewer.window.qt_viewer.view.camera.set_state({"rect": rect})
def on_resize(self, event): scale = 10000 r1 = self.viewbox_pos.camera.rect self.viewbox_fan.camera.rect = Rect(r1.left, r1.bottom * scale, r1.width, r1.height * scale) return
def bounds(self, b): self._bounds = Rect(b).normalized() b = self._bounds self.fshader['view'] = (b.left, b.right, b.bottom, b.top)
def zoom(self, factor, center=None): """ Zoom in (or out) at the given center Parameters ---------- factor : float or tuple Fraction by which the scene should be zoomed (e.g. a factor of 2 causes the scene to appear twice as large). center : tuple of 2-4 elements The center of the view. If not given or None, use the current center. """ if self._zoomed: return assert len(center) in (2, 3, 4) # Get scale factor, take scale ratio into account if np.isscalar(factor): scale = [factor, factor] else: if len(factor) != 2: raise TypeError("factor must be scalar or length-2 sequence.") scale = list(factor) if self.aspect is not None: scale[0] = scale[1] # Init some variables center = center if (center is not None) else self.center # Make a new object (copy), so that allocation will # trigger view_changed: rect = Rect(self.rect) if rect.right - rect.left < 0.1 and scale[0] < 1: return # Get space from given center to edges left_space = center[0] - rect.left right_space = rect.right - center[0] bottom_space = center[1] - rect.bottom top_space = rect.top - center[1] # Scale these spaces if self._zoom_axis == 'both' or self._zoom_axis == 'x': rect.left = center[0] - left_space * scale[0] rect.right = center[0] + right_space * scale[0] if self._zoom_axis == 'both' or self._zoom_axis == 'y': rect.bottom = center[1] - bottom_space * scale[1] rect.top = center[1] + top_space * scale[1] if self._ybounds is not None: if rect.bottom < self._ybounds[0]: rect.bottom = self._ybounds[0] if rect.top > self._ybounds[1]: rect.top = self._ybounds[1] if self._xbounds is not None: if rect.left < self._xbounds[0]: rect.left = self._xbounds[0] if rect.right > self._xbounds[1]: rect.right = self._xbounds[1] self.rect = rect self._zoomed = True for c in self._linked_panzoom: if c._zoomed: continue new_center = [] new_center.append(rescale(center[0], self._xbounds[1], c._xbounds[1])) new_center.append(rescale(center[1], self._ybounds[1], c._ybounds[1])) new_center.extend([0,1]) c.zoom(factor, np.array(new_center)) self._zoomed = False
def test_map_rect(): r = Rect((2, 7), (13, 19)) r1 = ST(scale=(2, 2), translate=(-10, 10)).map(r) assert r1 == Rect((-6, 24), (26, 38))
def __init__(self): super(SignalCamera, self).__init__(mag=1) self._limit_rect = Rect(0, 0, 1, 1)
def zoom(self, factor, center=None): """ Zoom in (or out) at the given center Parameters ---------- factor : float or tuple Fraction by which the scene should be zoomed (e.g. a factor of 2 causes the scene to appear twice as large). center : tuple of 2-4 elements The center of the view. If not given or None, use the current center. """ if self.zoom is None: return if self._zoomed: return assert len(center) in (2, 3, 4) # Get scale factor, take scale ratio into account if np.isscalar(factor): scale = [factor, factor] else: if len(factor) != 2: raise TypeError("factor must be scalar or length-2 sequence.") scale = list(factor) if self.aspect is not None: scale[0] = scale[1] # Init some variables center = center if (center is not None) else self.center # Make a new object (copy), so that allocation will # trigger view_changed: rect = Rect(self.rect) if rect.right - rect.left < 0.1 and scale[0] < 1: return # Get space from given center to edges left_space = center[0] - rect.left right_space = rect.right - center[0] bottom_space = center[1] - rect.bottom top_space = rect.top - center[1] # Scale these spaces if self._zoom_axis == 'both' or self._zoom_axis == 'x': rect.left = center[0] - left_space * scale[0] rect.right = center[0] + right_space * scale[0] if self._zoom_axis == 'both' or self._zoom_axis == 'y': rect.bottom = center[1] - bottom_space * scale[1] rect.top = center[1] + top_space * scale[1] if self._ybounds is not None: if rect.bottom < self._ybounds[0]: rect.bottom = self._ybounds[0] if rect.top > self._ybounds[1]: rect.top = self._ybounds[1] if self._xbounds is not None: if rect.left < self._xbounds[0]: rect.left = self._xbounds[0] if rect.right > self._xbounds[1]: rect.right = self._xbounds[1] self.rect = rect self._zoomed = True for c in self._linked_panzoom: if c._zoomed: continue new_center = [] new_center.append( rescale(center[0], self._xbounds[1], c._xbounds[1])) new_center.append( rescale(center[1], self._ybounds[1], c._ybounds[1])) new_center.extend([0, 1]) c.zoom(factor, np.array(new_center)) self._zoomed = False