def __init__(self, layer): # Create a compound visual with the following four subvisuals: # Markers: corresponding to the vertices of the interaction box or the # shapes that are used for highlights. # Lines: The lines of the interaction box used for highlights. # Mesh: The mesh of the outlines for each shape used for highlights. # Mesh: The actual meshes of the shape faces and edges node = Compound([Mesh(), Mesh(), Line(), Markers(), Text()]) super().__init__(layer, node) self.layer.events.edge_width.connect(self._on_data_change) self.layer.events.edge_color.connect(self._on_data_change) self.layer.events.face_color.connect(self._on_data_change) self.layer.text._connect_update_events(self._on_text_change, self._on_blending_change) self.layer.events.highlight.connect(self._on_highlight_change) self._reset_base() self._on_data_change() self._on_highlight_change()
def __init__(self, scale_bar, camera, parent=None, order=0): self._scale_bar = scale_bar self._camera = camera self._data = np.array([ [0, 0, -1], [1, 0, -1], [0, -5, -1], [0, 5, -1], [1, -5, -1], [1, 5, -1], ]) self._default_color = np.array([1, 0, 1, 1]) self._target_length = 100 self._scale = 1 self.node = Line(connect='segments', method='gl', parent=parent, width=3) self.node.order = order self.node.transform = STTransform() self.text_node = Text(pos=[0, 0], parent=parent) self.text_node.order = order self.text_node.transform = STTransform() self.text_node.font_size = 10 self.text_node.anchors = ('center', 'center') self.text_node.text = f'{1}' self._scale_bar.events.visible.connect(self._on_visible_change) self._scale_bar.events.colored.connect(self._on_data_change) self._scale_bar.events.background_color.connect(self._on_data_change) self._scale_bar.events.ticks.connect(self._on_data_change) self._scale_bar.events.position.connect(self._on_position_change) self._camera.events.zoom.connect(self._on_zoom_change) self._on_visible_change(None) self._on_data_change(None) self._on_position_change(None)
def __init__(self, layer): # Create a compound visual with the following four subvisuals: # Lines: The lines of the interaction box used for highlights. # Markers: The the outlines for each point used for highlights. # Markers: The actual markers of each point. node = Compound([Markers(), Markers(), Line(), Text()]) super().__init__(layer, node) self.layer.events.symbol.connect(self._on_data_change) self.layer.events.edge_width.connect(self._on_data_change) self.layer.events.edge_color.connect(self._on_data_change) self.layer._edge.events.colors.connect(self._on_data_change) self.layer._edge.events.color_properties.connect(self._on_data_change) self.layer.events.face_color.connect(self._on_data_change) self.layer._face.events.colors.connect(self._on_data_change) self.layer._face.events.color_properties.connect(self._on_data_change) self.layer.text._connect_update_events(self._on_text_change, self._on_blending_change) self.layer.events.highlight.connect(self._on_highlight_change) self._on_data_change() self._reset_base()
def __init__(self, viewer, parent=None, order=1e6): self._viewer = viewer self.node = Text(pos=(0, 0), parent=parent) self.node.order = order self.node.transform = STTransform() self.node.font_size = self._viewer.text_overlay.font_size self.node.anchors = ("center", "center") self._viewer.text_overlay.events.visible.connect( self._on_visible_change) self._viewer.text_overlay.events.text.connect(self._on_data_change) self._viewer.text_overlay.events.color.connect(self._on_text_change) self._viewer.text_overlay.events.font_size.connect( self._on_text_change) self._viewer.text_overlay.events.position.connect( self._on_position_change) self._viewer.camera.events.zoom.connect(self._on_position_change) self._on_visible_change(None) self._on_data_change(None) self._on_text_change(None) self._on_position_change(None)
def test_text(): """Test basic text support""" with TestingCanvas(bgcolor='w', size=(92, 92), dpi=92) as c: pos = [92 // 2] * 2 text = Text('testing', font_size=20, color='k', pos=pos, anchor_x='center', anchor_y='baseline') c.draw_visual(text) # Test image created in Illustrator CS5, 1"x1" output @ 92 DPI assert_image_approved("screenshot", 'visuals/text1.png') text.text = ['foo', 'bar'] text.pos = [10, 10] # should auto-replicate try: text.pos = [10] except Exception: pass else: raise AssertionError('Exception not raised') c.update() c.app.process_events() text.pos = [[10, 10], [10, 20]] text.text = 'foobar' c.update() c.app.process_events()
def on_init(self, event): self.text = Text('Initialized', font_size=40., anchor_x='left', anchor_y='top', parent=[self.vb_0.scene, self.vb_1.scene])
def __init__(self): self.clamp_filter = ClampSizeFilter() super().__init__([Markers(), Markers(), Line(), Text()]) self.attach(self.clamp_filter) self.scaling = True
def __init__(self, graph_index=None, graph_time=None, graph_position=None, graph_error=None, graph_fan=None, graph_target=None): self.graph_index, self.graph_time, self.graph_position, self.graph_error, self.graph_fan, self.graph_target = graph_index, graph_time, graph_position, graph_error, graph_fan, graph_target self.last_graph_index = graph_index.value - 1 self.line_opacity = 0.8 self.data_pos = np.zeros((0, 2), dtype=np.float32) self.data_pos_error = np.zeros((0, 2), dtype=np.float32) self.color = np.ones((0, 4), dtype=np.float32) self.data_fan = np.zeros((0, 2), dtype=np.float32) self.data_target = np.zeros((0, 2), dtype=np.float32) self.canvas = scene.SceneCanvas( keys='interactive', show=True, title='Ping-Pong Ball PID Oscilloscope') grid = self.canvas.central_widget.add_grid(spacing=0) #https://github.com/vispy/vispy/blob/master/vispy/scene/cameras/panzoom.py self.viewbox_fan = grid.add_view(row=0, col=1, camera='panzoom', parent=self.canvas.scene) self.viewbox_pos = grid.add_view(row=0, col=1, camera='panzoom', parent=self.canvas.scene) self.viewbox_pos.events.resize.connect(self.on_resize) # add some axes x_axis = scene.AxisWidget(orientation='bottom') x_axis.stretch = (1, 0.1) grid.add_widget(x_axis, row=1, col=1) x_axis.link_view(self.viewbox_pos) y_axis = scene.AxisWidget(orientation='left', text_color='red') y_axis.stretch = (0.1, 1) grid.add_widget(y_axis, row=0, col=0) y_axis.link_view(self.viewbox_pos) y2_axis = scene.AxisWidget(orientation='right', text_color='green') y2_axis.stretch = (0.1, 10) grid.add_widget(y2_axis, row=0, col=2) y2_axis.link_view(self.viewbox_fan) # y2_axis.transform = STTransform(scale=(1, 0.2, 1)) t1 = Text('Detected Ball Position [m]', parent=self.canvas.scene, color='red') t1.font_size = 10 # t1.pos = self.canvas.size[0] // 2, self.canvas.size[1] // 3 t1.pos = 167, 20 t2 = Text('Detected Ball Position Error [m]', parent=self.canvas.scene, color='yellow') t2.font_size = 10 t2.pos = 185, 35 t3 = Text('Fan RPM [RPM]', parent=self.canvas.scene, color='green') t3.font_size = 10 t3.pos = 130, 50 t4 = Text('Target Height [m]', parent=self.canvas.scene, color='blue') t4.font_size = 10 t4.pos = 135, 65 # add a line plot inside the viewbox self.line_pos = None self.line_pos_error = None self.line_target = None self.line_fan = None # add horizontal lines scene.InfiniteLine(0.0, [0.5, 0.5, 0.5, 0.5], vertical=False, parent=self.viewbox_pos.scene) # auto-scale to see the whole line. self.viewbox_pos.camera.set_range() self.auto_scale = True self.auto_scroll = False self.canvas.events.mouse_press.connect(self.on_mouse_press) self.canvas.events.mouse_release.connect(self.on_mouse_release) self.canvas.events.key_press.connect(self.on_key_press) return
# Create canvas with a viewbox at the lower half canvas = scene.SceneCanvas(keys='interactive') vb = scene.widgets.ViewBox(parent=canvas.scene, border_color='b') vb.camera = scene.TurntableCamera(elevation=30, azimuth=30, up='+z') axis = scene.visuals.XYZAxis(parent=vb.scene) vb.camera.rect = 0, 0, 1, 1 @canvas.events.resize.connect def resize(event=None): vb.pos = 1, canvas.size[1] // 2 - 1 vb.size = canvas.size[0] - 2, canvas.size[1] // 2 - 2 t1 = Text('Text in root scene (24 pt)', parent=canvas.scene, color='red') t1.font_size = 24 t1.pos = canvas.size[0] // 2, canvas.size[1] // 3 t2 = Text('Text in viewbox (18 pt)', parent=vb.scene, color='green', rotation=30) t2.font_size = 18 t2.pos = 0.5, 0.3 # Add a line so you can see translate/scale of camera N = 1000 linedata = np.empty((N, 2), np.float32) linedata[:, 0] = np.linspace(0, 1, N) linedata[:, 1] = np.random.uniform(0.5, 0.1, (N, ))
def on_timer(*args, **kwargs): # Change Source Radii and Connectivity Values if self.time_cache is None: time_inc = (args[0].dt * self.timescaling) self.displayed_time = self.loop_shift + ( self.displayed_time + time_inc) % ( (np.shape(self.sources[0].data)[1] / self.metadata['fs']) - self.loop_shift) else: self.displayed_time = self.loop_shift + (self.time_cache) % ( (np.shape(self.sources[0].data)[1] / self.metadata['fs']) - self.loop_shift) timepoint = int(self.displayed_time * self.metadata['fs']) for source in self.sources: source._update_radius(timepoint=timepoint) for connect in self.connect: connect._update_time(timepoint=timepoint) arduino_control(self.control_method) self.update_target_positions() self.update_carousel() self.update_visibility() self._prev_carousel_choice = self._carousel_choice if len(self._userdistance) > 2: self._userdistance = [-1] # Update Time Display t_str = str(round(self.displayed_time, 3)) + ' s' if not hasattr(self, '_time'): self._time = Text(t_str, parent=self.view.canvas.scene, color='white') else: self._time.text = t_str self._time.anchors = ('right', 'bottom') self._time.font_size = self.view.canvas.size[1] // 200 self._time.pos = (49) * self.view.canvas.size[0] // 50, ( 19) * self.view.canvas.size[1] // 20 self._time.update() # Ease to New Positions if Triggered if self.ease_xyz: self.ease_xyz = False for source in self.sources: out = source._ease_to_target_position() if out: self.ease_xyz = True for connect in self.connect: out = connect._ease_to_target_position() if out: self.ease_xyz = True # if hasattr(self.view.wc, 'camera'): # diff_az = self.target_azimuth - self.view.wc.camera.azimuth # diff_el = self.target_elevation - self.view.wc.camera.elevation # # Ease scene rotation # if (diff_az != 0.) | (diff_el != 0.): # # Flip target and current (since I cannot find a way to update the shortcuts directly) # if self.first_ease: # temp_ = self.target_elevation # self.target_elevation = self.view.wc.camera.elevation # self.view.wc.camera.elevation = temp_ # temp_ = self.target_azimuth # self.target_azimuth = self.view.wc.camera.azimuth # self.view.wc.camera.azimuth = temp_ # self.first_ease = False # if (abs(diff_az) > 0.001) | (abs(diff_el) > 0.001): # self.view.wc.camera.azimuth += .1*(diff_az) # self.view.wc.camera.elevation += .1*(diff_el) # print('updating rotation') # if self.first_ease: # self.first_ease = False # else: # self.view.wc.camera.azimuth = self.target_azimuth # self.view.wc.camera.elevation = self.target_elevation # self.first_ease = True #Iterate scene rotation # else: self.view.wc.camera.azimuth += self.rotation self.view.wc.canvas.update()
Demonstrate the use of the vispy console. Note how the console size is independent of the canvas scaling. """ import sys from vispy import scene, app from vispy.scene.widgets import Console from vispy.scene.visuals import Text canvas = scene.SceneCanvas(keys='interactive', size=(400, 400)) grid = canvas.central_widget.add_grid() vb = scene.widgets.ViewBox(border_color='b') vb.camera.rect = -1, -1, 2, 2 grid.add_widget(vb, row=0, col=0) text = Text('Starting timer...', color='w', font_size=24, parent=vb.scene) console = Console(text_color='g', font_size=12., border_color='g') grid.add_widget(console, row=1, col=0) def on_timer(event): text.text = 'Tick #%s' % event.iteration if event.iteration > 1 and event.iteration % 10 == 0: console.clear() console.write('Elapsed:\n %s' % event.elapsed) canvas.update() timer = app.Timer(2.0, connect=on_timer, start=True)
def __init__(self): super().__init__([Mesh(), Mesh(), Line(), Markers(), Text()])
def on_init(self, event): self.text = Text('Initialized', font_size=40., parent=[self.vb_0.scene, self.vb_1.scene])
def scene_building(recon_algos): # Prepare canvas canvas = scene.SceneCanvas(keys='interactive', size=(1024, 768), show=True) # canvas.measure_fps() # Set up a viewbox to display the image with interactive pan/zoom view = canvas.central_widget.add_view() # Set whether we are emulating a 3D texture emulate_texture = False # Create the volume visuals for the different reconstructions volume1 = scene.visuals.Volume(recon_algos[0], parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) volume2 = scene.visuals.Volume(recon_algos[1], parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) volume3 = scene.visuals.Volume(recon_algos[2], parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) volume4 = scene.visuals.Volume(recon_algos[3], parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) volume5 = scene.visuals.Volume(recon_algos[4], parent=view.scene, threshold=0.225, emulate_texture=emulate_texture) #volume1.transform = scene.STTransform(translate=(64, 64, 0)) # Hacky cyclic volume display setup: volume1.visible = True # set first volume as visible, then switch with 3 volume2.visible = False volume3.visible = False volume4.visible = False volume5.visible = False t1 = Text('ART reconstruction', parent=canvas.scene, color='white') t1.font_size = 18 t1.pos = canvas.size[0] // 2, canvas.size[1] - 10 t2 = Text('fbp reconstruction', parent=canvas.scene, color='white') t2.font_size = 18 t2.pos = canvas.size[0] // 2, canvas.size[1] - 10 t3 = Text('sirt reconstruction', parent=canvas.scene, color='white') t3.font_size = 18 t3.pos = canvas.size[0] // 2, canvas.size[1] - 10 t4 = Text('ospml_quad reconstruction', parent=canvas.scene, color='white') t4.font_size = 18 t4.pos = canvas.size[0] // 2, canvas.size[1] - 10 t5 = Text('pml_quad reconstruction', parent=canvas.scene, color='white') t5.font_size = 18 t5.pos = canvas.size[0] // 2, canvas.size[1] - 10 t1.visible = True t2.visible = False t3.visible = False t4.visible = False t5.visible = False # Implement axis connection with cam2 @canvas.events.mouse_move.connect def on_mouse_move(event): if event.button == 1 and event.is_dragging: axis.transform.reset() axis.transform.rotate(cam2.roll, (0, 0, 1)) axis.transform.rotate(cam2.elevation, (1, 0, 0)) axis.transform.rotate(cam2.azimuth, (0, 1, 0)) axis.transform.scale((50, 50, 0.001)) axis.transform.translate((50., 50.)) axis.update() # Implement key presses @canvas.events.key_press.connect def on_key_press(event): global opaque_cmap, translucent_cmap if event.text == '1': cam_toggle = {cam1: cam2, cam2: cam3, cam3: cam1} view.camera = cam_toggle.get(view.camera, cam2) print(view.camera.name + ' camera') if view.camera is cam2: axis.visible = True else: axis.visible = False elif event.text == '2': methods = ['mip', 'translucent', 'iso', 'additive'] method = methods[(methods.index(volume1.method) + 1) % 4] print("Volume render method: %s" % method) cmap = opaque_cmap if method in [ 'mip', 'iso'] else translucent_cmap volume1.method = method volume1.cmap = cmap elif event.text == '3': # hacky toogle between different reconstructed volumes if(volume1.visible): volume1.visible = False volume2.visible = True t1.visible = False t2.visible = True # t1.update() elif(volume2.visible): volume2.visible = False volume3.visible = True t2.visible = False t3.visible = True elif(volume3.visible): volume3.visible = False volume4.visible = True t3.visible = False t4.visible = True elif(volume4.visible): volume4.visible = False volume5.visible = True t4.visible = False t5.visible = True else: volume5.visible = False volume1.visible = True t5.visible = False t1.visible = True elif event.text == '4': if volume1.method in ['mip', 'iso']: cmap = opaque_cmap = next(opaque_cmaps) else: cmap = translucent_cmap = next(translucent_cmaps) volume1.cmap = volume2.cmap = volume3.cmap = volume4.cmap volume5.cmap = cmap elif event.text == '0': cam1.set_range() cam3.set_range() elif event.text != '' and event.text in '[]': s = -0.025 if event.text == '[' else 0.025 volume1.threshold += s #volume2.threshold += s th = volume1.threshold if volume1.visible else volume2.threshold print("Isosurface threshold: %0.3f" % th) # for testing performance #@canvas.connect # def on_draw(ev): # canvas.update() # @canvas.connect # def on_timer(ev): # # Animation speed based on global time. # t = event.elapsed # c = Color(self.color).rgb # # Simple sinusoid wave animation. # s = abs(0.5 + 0.5 * math.sin(t)) # self.context.set_clear_color((c[0] * s, c[1] * s, c[2] * s, 1)) # self.update() # Create three cameras (Fly, Turntable and Arcball) fov = 60. cam1 = scene.cameras.FlyCamera(parent=view.scene, fov=fov, name='Fly') cam2 = scene.cameras.TurntableCamera(parent=view.scene, fov=fov, name='Turntable') cam3 = scene.cameras.ArcballCamera( parent=view.scene, fov=fov, name='Arcball') view.camera = cam2 # Select turntable at first # Create an XYZAxis visual axis = scene.visuals.XYZAxis(parent=view) # view.scene tout court s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1)) affine = s.as_affine() axis.transform = affine # Setup colormap iterators opaque_cmaps = cycle(get_colormaps()) translucent_cmaps = cycle([TransFire(), TransGrays()]) opaque_cmap = next(opaque_cmaps) translucent_cmap = next(translucent_cmaps) # TODO: add a colorbar, fix error: AttributeError: module 'vispy.scene' has no attribute 'ColorBarWidget' #grid = canvas.central_widget.add_grid(margin=10) # cbar_widget = scene.ColorBarWidget(cmap=translucent_cmaps, orientation="right") #cmap="cool" # grid.add_widget(cbar_widget) # cbar_widget.pos = (800, 600)#(300, 100) # cbar_widget.border_color = "#212121" # grid.bgcolor = "#ffffff" # Create a rotation transform: # tr = MatrixTransform() #TODO: wait 0.5.0 to re-add MatrixTransform # Let's record a .gif: gif_file = Path("reconstruct_animation.mp4") if gif_file.is_file(): print('reconstruct_animation.mp4 is already in the folder, please delete it to get a new one') else: print('Let\'s record a .mp4 of the reconstructed volume:') n_steps = 450 # 360 step_angle = 0.8 # 1. # [] #0.1 fail, 0, 1 fail, (0.5, 0.5, 0.5)ok rotation_axis = np.array([0, 0, 1]) # rt=scene.AffineTransform() #volume1.transform = rt #volume1.transform.rotate(angle=step_angle, axis=rotation_axis) #volume1.transform.translate([1, 1, 0]) axis.visible = False #view.camera.set_range(x=[-3, 3]) writer = imageio.get_writer( 'reconstruct_animation.mp4', fps=50, quality=8) # TODO: add a progress bar gif_bar = progressbar.ProgressBar( redirect_stdout=True, max_value=n_steps) gif_bar.start() for i in range(n_steps): # * 2): im = canvas.render() writer.append_data(im) view.camera.transform.translate([1.8, -1.8, 0]) view.camera.transform.rotate(step_angle, rotation_axis) #volume1.transform.rotate(angle=step_angle, axis=rotation_axis) gif_bar.update(i) gif_bar.finish() writer.close() axis.visible = True
def __init__(self, viewer, parent=None, order=0): self._viewer = viewer self._scale = 1 # Target axes length in canvas pixels self._target_length = 80 # CMYRGB for 6 axes data in x, y, z, ... ordering self._default_color = [ [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], ] # Text offset from line end position self._text_offsets = 0.1 * np.array([1, 1, 1]) # note order is x, y, z for VisPy self._line_data2D = np.array([[0, 0, 0], [1, 0, 0], [0, 0, 0], [0, 1, 0]]) self._line_data3D = np.array([[0, 0, 0], [1, 0, 0], [0, 0, 0], [0, 1, 0], [0, 0, 0], [0, 0, 1]]) # note order is x, y, z for VisPy self._dashed_line_data2D = np.concatenate( [[[1, 0, 0], [0, 0, 0]], make_dashed_line(4, axis=1)], axis=0, ) self._dashed_line_data3D = np.concatenate( [ [[1, 0, 0], [0, 0, 0]], make_dashed_line(4, axis=1), make_dashed_line(8, axis=2), ], axis=0, ) # note order is x, y, z for VisPy vertices = np.empty((0, 3)) faces = np.empty((0, 3)) for axis in range(2): v, f = make_arrow_head(self._NUM_SEGMENTS_ARROWHEAD, axis) faces = np.concatenate([faces, f + len(vertices)], axis=0) vertices = np.concatenate([vertices, v], axis=0) self._default_arrow_vertices2D = vertices self._default_arrow_faces2D = faces.astype(int) vertices = np.empty((0, 3)) faces = np.empty((0, 3)) for axis in range(3): v, f = make_arrow_head(self._NUM_SEGMENTS_ARROWHEAD, axis) faces = np.concatenate([faces, f + len(vertices)], axis=0) vertices = np.concatenate([vertices, v], axis=0) self._default_arrow_vertices3D = vertices self._default_arrow_faces3D = faces.astype(int) self.node = Compound( [Line(connect='segments', method='gl', width=3), Mesh(), Text()], parent=parent, ) self.node.transform = STTransform() self.node.order = order # Add a text node to display axes labels self.text_node = self.node._subvisuals[2] self.text_node.font_size = 10 self.text_node.anchors = ('center', 'center') self.text_node.text = f'{1}' self._viewer.events.theme.connect(self._on_data_change) self._viewer.axes.events.visible.connect(self._on_visible_change) self._viewer.axes.events.colored.connect(self._on_data_change) self._viewer.axes.events.dashed.connect(self._on_data_change) self._viewer.axes.events.labels.connect(self._on_data_change) self._viewer.axes.events.arrows.connect(self._on_data_change) self._viewer.dims.events.order.connect(self._on_data_change) self._viewer.dims.events.ndisplay.connect(self._on_data_change) self._viewer.dims.events.axis_labels.connect(self._on_data_change) self._viewer.camera.events.zoom.connect(self._on_zoom_change) self._on_visible_change(None) self._on_data_change(None)
def __init__(self): super().__init__([Markers(), Markers(), Line(), Text()]) self.scaling = True
's' - save still from canvas 'a' - begin animation to rotate fractal ''' # INITALIZING KEY PRESS VARIABLES # Still images still_num = 1 num_frames = 20 # Loading data loaded_data_later = False # boolean to determine if data has been loaded # User message usr_message = Text('Message to user', parent=canvas.scene, color=(1, 1, 1, 0), anchor_x='left', anchor_y='top') # starts off invisible usr_message.font_size = 15 usr_message.pos = canvas.size[0] // 22, canvas.size[1] // 22 fade_out = Timer(interval=0.07, iterations=num_frames) # Connecting timer to fading out function @fade_out.connect def text_fade(event): transparency = 1 - ((event.iteration + 1) * (1 / num_frames)) usr_message.color = (1, 1, 1, transparency) # Implement key presses
def __init__(self, data, axis=-1, sf=1., color='random', title=None, space=2., scale=(.98, .9), font_size=10., width=1., method='gl', force_shape=None): """Init.""" # =========================== CHECKING =========================== assert isinstance(data, np.ndarray) and (data.ndim <= 3) assert isinstance(axis, int) assert isinstance(sf, (int, float)) assert isinstance(space, (int, float)) assert isinstance(scale, (tuple, list)) and len(scale) == 2 # =========================== VISUALS =========================== visuals.Visual.__init__(self, vertex_shader, fragment_shader) self.set_gl_state('translucent', depth_test=True, cull_face=False, blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self._draw_mode = 'line_strip' self._txt = Text(bold=False, font_size=font_size) # =========================== DATA =========================== # Keep some inputs : self._sh = data.shape self._n = self._sh[axis] self._axis = axis self._sf = sf self._color = color self.scale = scale self.space = space self._prep = PrepareData(axis=-1) self.width = width self.method = method # =========================== BUFFERS =========================== # Create buffers (for data, index and color) rnd_1 = np.zeros((3, ), dtype=np.float32) rnd_3 = np.zeros((1, 3), dtype=np.float32) self._dbuffer = gloo.VertexBuffer(rnd_1) self._ibuffer = gloo.VertexBuffer(rnd_3) self._cbuffer = gloo.VertexBuffer(rnd_3) # Send to the program : self.shared_program.vert['a_position'] = self._dbuffer self.shared_program.vert['a_index'] = self._ibuffer self.shared_program.vert['a_color'] = self._cbuffer self.shared_program.vert['u_size'] = (1, 1) self.shared_program.vert['u_n'] = len(self) # Set data : self.set_data(data, axis, color, title, force_shape) self.freeze()
def __init__(self, viewer, parent=None, order=0): self._viewer = viewer self._data = np.array([ [0, 0, -1], [1, 0, -1], [0, -5, -1], [0, 5, -1], [1, -5, -1], [1, 5, -1], ]) self._target_length = 150 self._scale = 1 self._quantity = None self._unit_reg = None self.line_node = Line(connect='segments', method='gl', parent=parent, width=3) self.line_node.order = order + 1 self.line_node.transform = STTransform() # In order for the text and box to always appear centered on the scale # bar, the text and rect nodes should use the line node as the parent. self.text_node = Text(pos=[0.5, -1], parent=self.line_node) self.text_node.order = order + 1 self.text_node.transform = STTransform() self.text_node.font_size = 10 self.text_node.anchors = ("center", "center") self.text_node.text = f"{1}px" self.rect_node = Rectangle( center=[0.5, 0.5], width=1.1, height=36, color=self._viewer.scale_bar.box_color, parent=self.line_node, ) self.rect_node.order = order self.rect_node.transform = STTransform() # the two canvas are not the same object, better be safe. self.rect_node.canvas._backend.destroyed.connect(self._set_canvas_none) self.line_node.canvas._backend.destroyed.connect(self._set_canvas_none) self.text_node.canvas._backend.destroyed.connect(self._set_canvas_none) assert self.rect_node.canvas is self.line_node.canvas assert self.line_node.canvas is self.text_node.canvas # End Note self._viewer.events.theme.connect(self._on_data_change) self._viewer.scale_bar.events.visible.connect(self._on_visible_change) self._viewer.scale_bar.events.colored.connect(self._on_data_change) self._viewer.scale_bar.events.ticks.connect(self._on_data_change) self._viewer.scale_bar.events.box_color.connect(self._on_data_change) self._viewer.scale_bar.events.color.connect(self._on_data_change) self._viewer.scale_bar.events.position.connect( self._on_position_change) self._viewer.camera.events.zoom.connect(self._on_zoom_change) self._viewer.scale_bar.events.font_size.connect(self._on_text_change) self._viewer.scale_bar.events.unit.connect(self._on_dimension_change) self._viewer.scale_bar.events.box.connect(self._on_visible_change) self._on_visible_change() self._on_data_change() self._on_dimension_change() self._on_position_change()
c = Canvas(show=True) c.title = 'Issue 5' c.view.camera.rect = (-1.08475e+07, 4.18788e+06), (2886.92, 2886.92) c.view.add_tiles_for_current_zoom() # add reference marker, using calculated x, y long, lat = -97.441296, 35.18048 x, y = mercantile.xy(long, lat) m_expected = Markers(parent=c.view.scene) m_expected.set_data(np.array([(x, y, 0)]), face_color=(0, 1, 1)) t_ok = Text( 'Expected position', pos=(x + 100, y), anchor_x='left', parent=c.view.scene, color=(0, 1, 1), ) t_ok.order = 10 m_bad = c.view.marker_at((long - 0.0005, lat), face_color=(1, 0, 0)) t_bad = Text( 'Actual position', pos=(long, lat), anchor_x='left', parent=c.view.scene, color=(1, 0, 0), ) t_bad.order = 10 t_bad.transform = MercatorTransform()
def __init__(self): scene.SceneCanvas.__init__(self, title='Glyphs', keys='interactive') self.font_size = 48. self.text = Text('', bold=True) self.apply_zoom()
def scattertime(pos, mfc=[1, 1, 1, 0.8], mec=[0, 0, 0, 0.8], mfs=5, mes=1, bgc=[1, 1, 1], scaling=False, symbol='disc', title='Vispy Canvas'): """ Display a scatter plot in 2D or 3D. Parameters ---------- pos : array The array of locations to display each symbol. mfc : Color | ColorArray The color used to draw each symbol interior. mec : Color | ColorArray The color used to draw each symbol outline. mfs : float or array The symbol size in px. mes : float | None The width of the symbol outline in pixels. bgc : Color The color used for the background. scaling : bool If set to True, marker scales when rezooming. symbol : str The style of symbol to draw ('disc', 'arrow', 'ring', 'clobber', 'square', 'diamond', 'vbar', 'hbar', 'cross', 'tailed_arrow', 'x', 'triangle_up', 'triangle_down', 'star'). """ # Create the Canvas, the Scene and the View canvas = scene.SceneCanvas(keys='interactive', show=True, bgcolor=bgc, title=title) canvas2 = scene.SceneCanvas(keys='interactive', size=(80, 80), show=True, bgcolor=bgc) view = canvas.central_widget.add_view() # Create the scatter plot scatter = visuals.Markers() scatter.set_data(pos, face_color=mfc[0, :, :], edge_color=mec, scaling=scaling, size=mfs, edge_width=mes, symbol=symbol) view.add(scatter) t1 = Text('frame (ms) : 0', parent=view.scene, color='black') # 2D Shape if pos.shape[1] == 2: # Set the camera properties view.camera = 'panzoom' # 3D Shape elif pos.shape[1] == 3: view.camera = 'turntable' global time time = 0 def update(ev): global time time += 1 t1.text = 'frame (ms) : ' + str(time) time = time % mfc.shape[0] scatter.set_data(pos=pos, face_color=mfc[time, :, :], edge_color=mec, scaling=scaling, size=mfs) if 10 < time < 25: # if 15 < time < 46 : canvas2.bgcolor = (0, 0, 0) else: canvas2.bgcolor = (1, 1, 1) timer = app.Timer(.2, connect=update, start=True) app.run()