def test_sphere(): """Test sphere function""" md = create_sphere(rows=10, cols=20, radius=10, method='latitude') radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10) md = create_sphere(subdivisions=5, radius=10, method='ico') radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10) md = create_sphere(rows=20, cols=20, depth=20, radius=10, method='cube') radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10)
def test_sphere(): """Test sphere function""" md = create_sphere(rows=10, cols=20, radius=10, method='latitude') radii = np.sqrt((md.get_vertices()**2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10) md = create_sphere(subdivisions=5, radius=10, method='ico') radii = np.sqrt((md.get_vertices()**2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10) md = create_sphere(rows=20, cols=20, depth=20, radius=10, method='cube') radii = np.sqrt((md.get_vertices()**2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10)
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 550)) self.meshes = [] self.rotation = AffineTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color self.meshes.append(visuals.MeshVisual(meshdata=mdata, color='r')) ## Mesh with pre-indexed vertices, per-face color ## Because vertices are pre-indexed, we get a different color ## every time a vertex is visited, resulting in sharp color ## differences between edges. verts = mdata.get_vertices(indexed='faces') nf = verts.size//9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis] fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = visuals.MeshVisual(vertices=verts, face_colors=fcolor) self.meshes.append(mesh) ## Mesh with unindexed vertices, per-vertex color ## Because vertices are unindexed, we get the same color ## every time a vertex is visited, resulting in no color differences ## between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size//3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = np.random.normal(size=nv) vcolor[:, 2] = np.linspace(0, 1, nv) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor)) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='flat')) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='smooth')) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation]) tr_sys = visuals.transforms.TransformSystem(self) tr_sys.visual_to_document = transform mesh.tr_sys = tr_sys self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 550)) self.meshes = [] self.rotation = AffineTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color self.meshes.append(visuals.MeshVisual(meshdata=mdata, color='r')) ## Mesh with pre-indexed vertices, per-face color ## Because vertices are pre-indexed, we get a different color ## every time a vertex is visited, resulting in sharp color ## differences between edges. verts = mdata.get_vertices(indexed='faces') nf = verts.size // 9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis] fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = visuals.MeshVisual(vertices=verts, face_colors=fcolor) self.meshes.append(mesh) ## Mesh with unindexed vertices, per-vertex color ## Because vertices are unindexed, we get the same color ## every time a vertex is visited, resulting in no color differences ## between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size // 3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = np.random.normal(size=nv) vcolor[:, 2] = np.linspace(0, 1, nv) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor)) self.meshes.append( visuals.MeshVisual(verts, faces, vcolor, shading='flat')) self.meshes.append( visuals.MeshVisual(verts, faces, vcolor, shading='smooth')) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 transform = ChainTransform([ STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation ]) tr_sys = visuals.transforms.TransformSystem(self) tr_sys.visual_to_document = transform mesh.tr_sys = tr_sys self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
def test_mesh_normals_length_scalar(): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' # Create visual. mdata = create_sphere(radius=1.0) mesh = scene.visuals.Mesh(meshdata=mdata, shading=None, color=(0.1, 0.1, 0.1, 1.0)) v.add(mesh) length = 0.5 normals_0_5 = scene.visuals.MeshNormals(mdata, color=(1, 0, 0), length=length) normals_0_5.parent = mesh rendered_length_0_5 = c.render() normals_0_5.parent = None length = 1.0 normals_1_0 = scene.visuals.MeshNormals(mdata, color=(1, 0, 0), length=length) normals_1_0.parent = mesh rendered_length_1_0 = c.render() normals_1_0.parent = None # There should be more red pixels with the longer normals. n_pixels_0_5 = np.sum(rendered_length_0_5[..., 0] > 128) n_pixels_1_0 = np.sum(rendered_length_1_0[..., 0] > 128) assert n_pixels_1_0 > n_pixels_0_5
def test_mesh_shading_filter(shading): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) # Create visual mdata = create_sphere(20, 40, radius=20) mesh = scene.visuals.Mesh(meshdata=mdata, shading=shading, color=(0.1, 0.3, 0.7, 0.9)) v.add(mesh) from vispy.visuals.transforms import STTransform mesh.transform = STTransform(translate=(20, 20)) mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01)) rendered = c.render()[..., 0] # R channel only if shading in ("flat", "smooth"): # there should be a gradient, not solid colors assert np.unique(rendered).size >= 28 # sphere/circle starts "dark" on the left and gets brighter # then hits a bright spot and decreases after invest_row = rendered[23].astype(np.float64) # overall, we should be increasing brightness up to a "bright spot" assert (np.diff(invest_row[:29]) >= -1).all() else: assert np.unique(rendered).size == 2
def test_mesh_shading_filter_enabled(shading): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' mdata = create_sphere(20, 30, radius=1) mesh = scene.visuals.Mesh(meshdata=mdata, shading=None, color=(0.2, 0.3, 0.7, 1.0)) shading_filter = ShadingFilter(shading=shading) mesh.attach(shading_filter) v.add(mesh) shading_filter.enabled = False rendered_without_shading = c.render() shading_filter.enabled = True rendered_with_shading = c.render() if shading is None: # There should be no shading applied, regardless of the value of # `enabled`. assert np.allclose(rendered_without_shading, rendered_with_shading) else: # The result should be different with shading applied. assert not np.allclose(rendered_without_shading, rendered_with_shading)
def generate_skeleton( truncated_icosahedron_vertices_coordinates, edges_between_vertices, sphere_radius=0.4, cylinder_radius=0.1, sphere_rows=10, sphere_cols=10, cylinder_rows=10, cylinder_cols=10, color=(1, 0.6, 0)): spheres_geometry = [] for i, vertex_coordinate in enumerate(truncated_icosahedron_vertices_coordinates): new_mesh = geometry.create_sphere(sphere_rows, sphere_cols, radius=sphere_radius) new_mesh.set_vertices(new_mesh.get_vertices() + vertex_coordinate, reset_normals=False) spheres_geometry.append(new_mesh) cylinders_geometry = [] for first_vertex_index, second_vertex_index in edges_between_vertices: first_vertex_coordinate = truncated_icosahedron_vertices_coordinates[first_vertex_index] second_vertex_coordinate = truncated_icosahedron_vertices_coordinates[second_vertex_index] cylinder = generate_cylinder_geometry(first_vertex_coordinate, second_vertex_coordinate, cylinder_rows, cylinder_cols, cylinder_radius, sphere_radius) cylinders_geometry.append(cylinder) final_object_vertices, final_object_faces = append_geometries(np.empty([0, 3], np.float32), np.empty([0, 3], np.uint32), spheres_geometry) final_object_vertices, final_object_faces = append_geometries(final_object_vertices, final_object_faces, cylinders_geometry) return scene.visuals.Mesh(vertices=final_object_vertices, faces=final_object_faces, color=color, shading='smooth')
def updateView(self, param): if param.dict["subdiv"] != param.dict["subdiv_old"]: subdiv = param.dict['subdiv'] md = create_sphere(radius=1, subdivisions=subdiv, method='ico') verts = md.get_vertices() print(verts.shape) faces = md.get_faces() gamma, phi = xyz_to_gp(verts) data = np.cos(5*gamma)+np.cos(phi*4)/2. param.dict["data"] = data self.sph.mesh.set_data(vertices=verts, faces=faces, vertex_values=data) param.dict["subdiv_old"] = param.dict["subdiv"] self.sph.mesh.cmap = param.dict['colormap'] self.cbar_widget.cmap = param.dict['colormap'] self.cbar_widget.nband = param.dict['nbr_band'] self.cbar_widget.banded = param.dict['banded'] v_min = 0.0 v_max = 1.0 if param.dict["data"] is not None: v_min = np.min(param.dict["data"], 0) v_max = np.max(param.dict["data"], 0) self.cbar_widget.clim = (v_min, v_max) self.sph.mesh.nband = param.dict['nbr_band'] self.sph.mesh.banded = param.dict['banded']
def add_chan(self, chan, color=CHAN_COLOR, chan_colors=None, values=None, limits_c=None, colormap='coolwarm', shift=(0, 0, 0)): """Add channels to visualization Parameters ---------- chan : instance of Channels channels to plot color : tuple 3-, 4-element tuple, representing RGB and alpha, between 0 and 1 chan_colors : ndarray array with colors for each channel values : ndarray array with values for each channel limits_c : tuple of 2 floats, optional min and max values to normalize the color colormap : str one of the colormaps in vispy shift : tuple of 3 floats shift all electrodes by this amount (unit and order depend on xyz coordinates of the electrodes) """ # larger if colors are meaningful if values is not None: meshdata = create_sphere(radius=3, method='ico') else: meshdata = create_sphere(radius=1.5, method='ico') chan_colors, limits = _prepare_chan_colors(color, chan_colors, values, limits_c, colormap) # store values in case we update the values self._chan_colormap = colormap self._chan_limits_c = limits for i, one_chan in enumerate(chan.chan): if chan_colors.ndim == 2: chan_color = chan_colors[i, :] else: chan_color = chan_colors mesh = SimpleMesh(meshdata, chan_color) mesh.transform = STTransform(translate=one_chan.xyz + shift) self._plt.view.add(mesh) self._chan.append(mesh)
def createsphere(self, nrows=20, ncols=20, radius=1.0): if not self.mesh: mdata = create_sphere(nrows, ncols, radius) self.mesh = visuals.Mesh(meshdata=mdata, vertex_colors='black', face_colors=(1.0, 0.0, 0.0, 1.0), color=(0.5, 0.5, 0.5, .75)) self.view.add(self.mesh) else: print(dir(self.mesh))
def test_mesh_normals_length_array(primitive): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' v.camera.fov = 90 # Create visual. meshdata = create_sphere(radius=1.0) mesh = scene.visuals.Mesh(meshdata=meshdata, shading=None, color=(0.1, 0.1, 0.1, 1.0)) v.add(mesh) if primitive == 'face': n_normals = len(meshdata.get_faces()) elif primitive == 'vertex': n_normals = len(meshdata.get_vertices()) lengths_0_5 = np.full(n_normals, 0.5, dtype=float) normals_0_5 = scene.visuals.MeshNormals(meshdata, primitive=primitive, color=(1, 0, 0), length=lengths_0_5) normals_0_5.parent = mesh rendered_lengths_0_5 = c.render() normals_0_5.parent = None lengths_1_0 = np.full(n_normals, 1.0, dtype=float) normals_1_0 = scene.visuals.MeshNormals(meshdata, primitive=primitive, color=(1, 0, 0), length=lengths_1_0) normals_1_0.parent = mesh rendered_lengths_1_0 = c.render() normals_1_0.parent = None # There should be more red pixels with the longer normals. n_pixels_0_5 = np.sum(rendered_lengths_0_5[..., 0] > 128) n_pixels_1_0 = np.sum(rendered_lengths_1_0[..., 0] > 128) assert n_pixels_1_0 > n_pixels_0_5 lengths_ramp = np.linspace(0.5, 1.0, n_normals, dtype=float) normals_ramp = scene.visuals.MeshNormals(meshdata, primitive=primitive, color=(1, 0, 0), length=lengths_ramp) normals_ramp.parent = mesh rendered_lengths_ramp = c.render() normals_ramp.parent = None # With the normals lengths from a ramp in [0.5, 1.0], there should be # more red pixels than with all normals of length 0.5 and less than # with all normals of length 1.0. n_pixels_ramp = np.sum(rendered_lengths_ramp[..., 0] > 128) assert n_pixels_0_5 < n_pixels_ramp < n_pixels_1_0
def __init__(self, position, radius, color, **kwargs): sphere_mesh = geometry.create_sphere( rows=int(radius * 30), cols=int(radius * 30), radius=radius, **kwargs ) sphere_buffer, faces = self.make_buffer(sphere_mesh) super(self.__class__, self).__init__(sphere_buffer, faces=faces, position=position, color=color) self.program['u_shininess'] = 16.0 self.program['u_specular_color'] = self.color[:3]
def __init__(self, position, radius, color, **kwargs): sphere_mesh = geometry.create_sphere(rows=int(radius * 30), cols=int(radius * 30), radius=radius, **kwargs) sphere_buffer, faces = self.make_buffer(sphere_mesh) super(self.__class__, self).__init__(sphere_buffer, faces=faces, position=position, color=color) self.program['u_shininess'] = 16.0 self.program['u_specular_color'] = self.color[:3]
def __init__(self, mu, cov, std=2., cols=15, rows=15, depth=15, subdivisions=3, method='latitude', vertex_colors=None, face_colors=None, color=(0.5, 0.5, 1, 1), edge_color=None, **kwargs): mesh = create_sphere(rows, cols, depth, radius=std, subdivisions=subdivisions, method=method) # Take the spherical mesh and project through the covariance, like you do # when sampling a multivariate gaussian. # https://en.wikipedia.org/wiki/Multivariate_normal_distribution#Drawing_values_from_the_distribution A = np.linalg.cholesky(cov) verts = mesh.get_vertices() verts2 = np.matmul(A[None, :, :], verts[:, :, None]) verts3 = verts2 + mu[None, :, None] mesh.set_vertices(np.squeeze(verts3)) self._mesh = MeshVisual(vertices=mesh.get_vertices(), faces=mesh.get_faces(), vertex_colors=vertex_colors, face_colors=face_colors, color=color) if edge_color: self._border = MeshVisual(vertices=mesh.get_vertices(), faces=mesh.get_edges(), color=edge_color, mode='lines') else: self._border = MeshVisual() CompoundVisual.__init__(self, [self._mesh, self._border], **kwargs) self.mesh.set_gl_state(polygon_offset_fill=True, polygon_offset=(1, 1), depth_test=True)
def test_mesh_normals_length_scale(): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' # Create visual. meshdata = create_sphere(radius=1.0) mesh = scene.visuals.Mesh(meshdata=meshdata, shading=None, color=(0.1, 0.1, 0.1, 1.0)) v.add(mesh) length = 1.0 length_scale_up = 2.0 length_scale_down = 0.5 normals = scene.visuals.MeshNormals(meshdata, color=(1, 0, 0), length=length) normals.parent = mesh rendered_length_default = c.render() normals.parent = None normals_scaled_up = scene.visuals.MeshNormals( meshdata, color=(1, 0, 0), length=length, length_scale=length_scale_up) normals_scaled_up.parent = mesh rendered_length_scaled_up = c.render() normals_scaled_up.parent = None normals_scaled_down = scene.visuals.MeshNormals( meshdata, color=(1, 0, 0), length=length, length_scale=length_scale_down) normals_scaled_down.parent = mesh rendered_length_scaled_down = c.render() normals_scaled_down.parent = None # There should be more red pixels with the scaled-up normals and less # with the ones scaled down. n_pixels_default = np.sum(rendered_length_default[..., 0] > 128) n_pixels_scaled_up = np.sum(rendered_length_scaled_up[..., 0] > 128) n_pixels_scaled_down = np.sum( rendered_length_scaled_down[..., 0] > 128) assert n_pixels_scaled_down < n_pixels_default < n_pixels_scaled_up
def create_sphere(self, point, time_point, radius): mdata = geometry.create_sphere(64, 64, radius=radius) color = point["color"] if isinstance(color, type(None)): color = "gray" sphere = scene.visuals.Mesh(meshdata=mdata, shading="flat", color=color) t = visuals.transforms.MatrixTransform() sphere.transform = t sphere.transform.translate(point.traj.loc[time_point, self.coords].values) self.points[point.idx] = (sphere, point) self.view.add(sphere) return sphere
def test_mesh_wireframe_filter(): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) # Create visual mdata = create_sphere(20, 40, radius=20) mesh = scene.visuals.Mesh(meshdata=mdata, shading=None, color=(0.1, 0.3, 0.7, 0.9)) wireframe_filter = WireframeFilter(color='red') mesh.attach(wireframe_filter) v.add(mesh) from vispy.visuals.transforms import STTransform mesh.transform = STTransform(translate=(20, 20)) mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01)) rendered_with_wf = c.render() assert np.unique(rendered_with_wf[..., 0]).size >= 50 wireframe_filter.enabled = False rendered_wo_wf = c.render() # the result should be completely different # assert not allclose pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_wf, rendered_wo_wf) wireframe_filter.enabled = True wireframe_filter.wireframe_only = True rendered_with_wf_only = c.render() # the result should be different from the two cases above pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_wf_only, rendered_with_wf) pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_wf_only, rendered_wo_wf) wireframe_filter.enabled = True wireframe_filter.wireframe_only = False wireframe_filter.faces_only = True rendered_with_faces_only = c.render() # the result should be different from the cases above pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_faces_only, rendered_with_wf) pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_faces_only, rendered_wo_wf) pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_faces_only, rendered_with_wf_only)
def __init__(self, data, istep=1, scale=1., colors='y', R=0.01): """ Initialize an NbodyCanvas data : 2d array, (Ntimesteps, Nparticles*9) position(3), velocity(3), and acceleration(9) of each particle istep : int advance timestep by this amount scale : float scale length colors : list of Nparticle size or 1 list of matplotlib colors """ scene.SceneCanvas.__init__(self, keys='interactive') view = self.central_widget.add_view() view.set_camera('turntable', mode='ortho', up='z', distance=1.0, azimuth=30., elevation=60.) self.view = view # Add a 3D axis to keep us oriented self.axis = scene.visuals.XYZAxis(parent=view.scene) self.timer = app.Timer(0.1, connect=self.on_timer, start=True) # create mesh of a phere self.mdata = create_sphere(20, 40, R) self.i = 0 self.istep = istep self.scale = scale self.meshes = [] self.d = data self.np = self.d.shape[1]/9 # number of particles self.nt = self.d.shape[0] # number of timesteps colors = list(colors) if len(colors) == 1: colors *= self.np else: assert len(colors) == self.np, "invalid number of colors" # add particles for the first time for (x, y, z), c in\ zip(np.vstack(np.split(self.d[self.i],self.np))[:,:3], colors): m = scene.visuals.Mesh( meshdata=self.mdata, color=c, shading='smooth') m.transform = scene.transforms.AffineTransform() m.transform.translate([x/self.scale, y/self.scale, z/self.scale]) self.view.add(m) self.meshes.append(m)
def test_mesh_shading_filter_colors(attribute): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: base_color_white = (1.0, 1.0, 1.0, 1.0) overlay_color_red = (1.0, 0.0, 0.0, 1.0) v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' mdata = create_sphere(20, 30, radius=1) mesh = scene.visuals.Mesh(meshdata=mdata, color=base_color_white) v.add(mesh) shading_filter = ShadingFilter( shading='smooth', # Set the light source on the side of # and around the camera to get a clearly # visible reflection. light_dir=(-5, -5, 5), # Activate all illumination types as # white light but reduce the intensity # to prevent saturation. ambient_light=0.3, diffuse_light=0.3, specular_light=0.3, # Get a wide highlight. shininess=4) mesh.attach(shading_filter) rendered_white = c.render() setattr(shading_filter, attribute, overlay_color_red) rendered_red = c.render() # The results should be different. assert not np.allclose(rendered_white, rendered_red) # There should be an equal amount of all colors in the white rendering. color_count_white = rendered_white.sum(axis=(0, 1)) r, g, b, _ = color_count_white assert r == g and r == b color_count_red = rendered_red.sum(axis=(0, 1)) # There should be more red in the red-colored rendering. r, g, b, _ = color_count_red assert r > g and r > b
def test_mesh_normals_length_method(length_method): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' # Create visual. meshdata = create_sphere(radius=1.0) mesh = scene.visuals.Mesh(meshdata=meshdata, shading=None, color=(0.1, 0.1, 0.1, 1.0)) v.add(mesh) # The code below should not raise. # XXX(asnt): Not sure how to better test `length_method`. normals = scene.visuals.MeshNormals(meshdata, color=(1, 0, 0), length_method=length_method) normals.parent = mesh _ = c.render()
def __init__(self, radius=1.0, cols=30, rows=30, depth=30, subdivisions=3, method='latitude', vertex_colors=None, face_colors=None, color=(0.5, 0.5, 1, 1), edge_color=None, **kwargs): EventEmitter.__init__(self) self._origin = np.array([0, 0, 0]) self._pos = np.array([0, 0, 0]) self._scale_factor = scale mesh = create_sphere(cols, rows, depth, radius=radius, subdivisions=subdivisions, method=method) self._mesh = MeshVisual(vertices=mesh.get_vertices(), faces=mesh.get_faces(), vertex_colors=vertex_colors, face_colors=face_colors, color=color) if edge_color: self._border = MeshVisual(vertices=mesh.get_vertices(), faces=mesh.get_edges(), color=edge_color, mode='lines') else: self._border = MeshVisual() CompoundVisual.__init__(self, [self._mesh, self._border], **kwargs) self.mesh.set_gl_state(polygon_offset_fill=True, polygon_offset=(1, 1), depth_test=True)
def create_sphere(self, point, time_point, radius): mdata = geometry.create_sphere(64, 64, radius=radius) color = point['color'] if isinstance(color, type(None)): color = "gray" sphere = scene.visuals.Mesh(meshdata=mdata, shading='flat', color=color) t = visuals.transforms.MatrixTransform() sphere.transform = t sphere.transform.translate(point.traj.loc[time_point, self.coords].values) self.points[point.idx] = (sphere, point) self.view.add(sphere) return sphere
def test_mesh_normals(): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' # Create visual. mdata = create_sphere(radius=1.0) mesh = scene.visuals.Mesh(meshdata=mdata, shading=None, color=(0.1, 0.1, 0.1, 1.0)) v.add(mesh) rendered_without_normals = c.render() # The color should be of low intensity. assert np.all((rendered_without_normals[..., 0:3]) < 32) face_normals = scene.visuals.MeshNormals(mdata, primitive="face", color=(1, 0, 0)) face_normals.parent = mesh rendered_with_face_normals = c.render() face_normals.parent = None # There should be some pixels with brighter red. assert np.sum(rendered_with_face_normals[..., 0] > 128) > 64 pytest.raises(AssertionError, np.testing.assert_allclose, rendered_without_normals, rendered_with_face_normals) vertex_normals = scene.visuals.MeshNormals(mdata, primitive="vertex", color=(0, 1, 0)) vertex_normals.parent = mesh rendered_with_vertex_normals = c.render() vertex_normals.parent = None # There should be some pixels with brighter green. assert np.sum(rendered_with_vertex_normals[..., 1] > 128) > 64 pytest.raises(AssertionError, np.testing.assert_allclose, rendered_without_normals, rendered_with_vertex_normals) pytest.raises(AssertionError, np.testing.assert_allclose, rendered_with_face_normals, rendered_with_vertex_normals)
def test_mesh_shading_filter(shading): size = (45, 40) with TestingCanvas(size=size, bgcolor="k") as c: v = c.central_widget.add_view(border_width=0) v.camera = 'arcball' mdata = create_sphere(20, 30, radius=1) mesh = scene.visuals.Mesh(meshdata=mdata, shading=shading, color=(0.2, 0.3, 0.7, 1.0)) v.add(mesh) rendered = c.render()[..., 0] # R channel only if shading in ("flat", "smooth"): # there should be a gradient, not solid colors assert np.unique(rendered).size >= 28 # sphere/circle is "dark" on the right and gets brighter as you # move to the left, then hits a bright spot and decreases after invest_row = rendered[34].astype(np.float64) # overall, we should be increasing brightness up to a "bright spot" assert (np.diff(invest_row[34:60]) <= 0).all() else: assert np.unique(rendered).size == 2
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 600)) brain = np.load(load_data_file('brain/brain.npz', force_download='2014-09-04')) #brain1 = scipy.io.loadmat('NewBESATri.mat') brain2 = brain1['t'] from numpy import genfromtxt my_data = genfromtxt('BESACOORD61.csv', delimiter=',') dataTest = brain['vertex_buffer'] color = dataTest['a_color'] color = color[750:1500] facesTest = brain['index_buffer'] n = 750 ps = 100 data = np.zeros(n, [('a_position', np.float32, 3), ('a_normal', np.float32, 3), ('a_color', np.float32, 3)]) #('a_size', np.float32, 1)]) import scipy.spatial tri = scipy.spatial.Delaunay(my_data) # points: np.array() of 3d points convex = tri.convex_hull indices = tri.simplices vertices = my_data[indices] data['a_position'] = my_data data['a_color'] = np.random.uniform(0, 1, (n, 3)) faces = brain2 faces = faces-1 vertices = my_data norm = np.zeros( vertices.shape, dtype=vertices.dtype ) #Create an indexed view into the vertex array using the array of three indices for triangles tris = vertices[faces] #Calculate the normal for all the triangles, by taking the cross product of the vectors v1-v0, and v2-v0 in each triangle n = np.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] ) # n is now an array of normals per triangle. The length of each normal is dependent the vertices, # we need to normalize these, so that our next step weights each normal equally. lens = np.sqrt( n[:,0]**2 + n[:,1]**2 + n[:,2]**2 ) n[:,0] /= lens n[:,1] /= lens n[:,2] /= lens norm[ faces[:,0] ] += n norm[ faces[:,1] ] += n norm[ faces[:,2] ] += n ''' Normalize a numpy array of 3 component vectors shape=(n,3) ''' lens = np.sqrt( norm[:,0]**2 + norm[:,1]**2 + norm[:,2]**2 ) norm[:,0] /= lens norm[:,1] /= lens norm[:,2] /= lens data['a_normal'] = norm #np.random.uniform(0, 1.0, (n, 3)) #10, 3, 3 #data['a_size'] = np.random.uniform(5*ps, 10*ps, n) u_linewidth = 1.0 u_antialias = 1.0 brain2 = np.uint32(brain2) convex = np.uint32(convex) data = data faces = brain2-1 #data = dataTest #faces = facesTest self.meshes = [] self.rotation = MatrixTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) #mdata['_faces'] =faces #mdata['_vertices']=data # Mesh with pre-indexed vertices, uniform color meshData=vispy.geometry.MeshData(vertices=data['a_position'], faces=None, edges=None, vertex_colors=None, face_colors=None) meshData._vertices = data['a_position'] meshData._faces = faces #meshData._face_colors = data['a_color'] #meshData._vertex_colors = data['a_color'] self.meshes.append(visuals.MeshVisual(meshdata=meshData, color='b')) #for mesh in self.meshes: # mesh.draw() # Mesh with pre-indexed vertices, per-face color # Because vertices are pre-indexed, we get a different color # every time a vertex is visited, resulting in sharp color # differences between edges. tris = vertices[faces] verts = data['a_position'] #mdata.get_vertices(indexed='faces') nf = 1496#verts.size//9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis] fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] #fcolor = data['a_color'] mesh = visuals.MeshVisual(vertices=tris, face_colors=fcolor) self.meshes.append(mesh) # Mesh with unindexed vertices, per-vertex color # Because vertices are unindexed, we get the same color # every time a vertex is visited, resulting in no color differences # between edges. #verts = mdata.get_vertices() faces = faces #mdata.get_faces() nv = verts.size//3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(.6, .6, nv) vcolor[:, 1] = np.random.normal(size=nv) vcolor[:, 2] = np.linspace(0.6, .6, nv) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor)) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='flat')) # self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='smooth')) # Lay out meshes in a grid grid = (1, 1) s = 300. / max(grid) #s = 500 for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] / grid[1] + 2 transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, s)), self.rotation]) mesh.transform = transform mesh.transforms.scene_transform = STTransform(scale=(.01, .01, .00001)) self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.00016)
vmax=8., under='gray', over='red') sc.add_to_subplot(s_obj_data, row=1, col=2, title='Color sources using data') cb_data = ColorbarObj(s_obj_data, cblabel='Random data', border=False, **CBAR_STATE) sc.add_to_subplot(cb_data, row=1, col=3, width_max=60) """Display only sources in the left hemisphere """ s_obj_left = SourceObj('S_left', xyz, color='#ab4642') s_obj_left.set_visible_sources('left') sc.add_to_subplot(s_obj_left, row=2, col=0, title='Display sources in left hemisphere') """Create a sphere using VisPy """ sphere = create_sphere(rows=100, cols=100, radius=50) sphere_vertices = sphere.get_vertices() """Force sources to fit on the vertices of the sphere. Then, we color sources according to the hemisphere (left=purple, right=yellow) """ s_obj_fit = SourceObj('Fit', xyz, symbol='diamond') s_obj_fit.fit_to_vertices(sphere_vertices) df_tal = s_obj_fit.analyse_sources(roi_obj='talairach') s_obj_fit.color_sources(analysis=df_tal, color_by='hemisphere', roi_to_color={'Left': 'purple', 'Right': 'yellow'}) sc.add_to_subplot(s_obj_fit, row=2, col=1, title="Force sources to fit on a sphere") """Use the same sphere to display only sources that are inside """
def __init__(self): app.Canvas.__init__(self, keys='interactive') self.meshes = [] self.rotation = AffineTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color verts = mdata.get_vertices(indexed='faces') mesh = ModularMesh(pos=verts, color=(1, 0, 0, 1)) self.meshes.append(mesh) # Mesh with pre-indexed vertices, per-face color # Because vertices are pre-indexed, we get a different color # every time a vertex is visited, resulting in sharp color # differences between edges. nf = verts.size//9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis] fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = ModularMesh(pos=verts, color=fcolor) self.meshes.append(mesh) # Mesh with unindexed vertices, per-vertex color # Because vertices are unindexed, we get the same color # every time a vertex is visited, resulting in no color differences # between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size//3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = np.random.normal(size=nv) vcolor[:, 2] = np.linspace(0, 1, nv) mesh = ModularMesh(pos=verts, faces=faces, color=vcolor) self.meshes.append(mesh) # Mesh colored by vertices + grid contours mesh = ModularMesh(pos=verts, faces=faces) mesh.color_components = [VertexColorComponent(vcolor), GridContourComponent(spacing=(0.13, 0.13, 0.13))] self.meshes.append(mesh) # Phong shaded mesh mesh = ModularMesh(pos=verts, faces=faces) normal_comp = VertexNormalComponent(mdata) mesh.color_components = [VertexColorComponent(vcolor), GridContourComponent(spacing=(0.1, 0.1, 0.1)), ShadingComponent(normal_comp, lights=[((-1, 1, -1), (1.0, 1.0, 1.0))], ambient=0.2)] self.meshes.append(mesh) # Phong shaded mesh, flat faces mesh = ModularMesh(pos=mdata.get_vertices(indexed='faces')) normal_comp = VertexNormalComponent(mdata, smooth=False) mesh.color_components = [ VertexColorComponent(vcolor[mdata.get_faces()]), GridContourComponent(spacing=(0.1, 0.1, 0.1)), ShadingComponent(normal_comp, lights=[((-1, 1, -1), (1.0, 1.0, 1.0))], ambient=0.2)] self.meshes.append(mesh) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 mesh.transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation]) mesh.tr_sys = visuals.transforms.TransformSystem(self) mesh.tr_sys.visual_to_document = mesh.transform self.size = (800, 800) self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
def plot_secant_crossings(self, radius=None, **kwargs): crossings = self.raw_crossings(**kwargs) if radius is None: radii = self.points - np.average(self.points, axis=0) radius = 2.5 * np.max(np.sqrt(np.sum(radii**2, axis=1))) unique_crossings = [] crossings_done = set() for crossing in crossings: if crossing[0] in crossings_done: continue crossings_done.add(crossing[1]) unique_crossings.append(crossing) points = self.points lines = [] for i, crossing in enumerate(unique_crossings): start1, end1, height1, sign1 = crossing for other_crossing in unique_crossings[i+1:]: start2, end2, height2, sign2 = other_crossing if not (start2 > start1 and end1 > start2 and end2 > end1): continue start_point1 = points[int(start1)] start_point1 += (start1 - int(start1)) * ( points[int(start1) + 1] - points[int(start1)]) segment_point1s = points[int(start1) + 1:int(start2) + 1] end_point1 = points[int(start2)] end_point1 += (start2 - int(start2)) * ( points[int(start2) + 1] - points[int(start2)]) segment1 = np.vstack( [start_point1, segment_point1s, end_point1]) # start_point2 = points[int(end1)] start_point2 += (end1 - int(end1)) * ( points[int(end1) + 1] - points[int(end1)]) segment_point2s = points[int(end1) + 1:int(end2) + 1] end_point2 = points[int(end2)] end_point2 += (end2 - int(end2)) * ( points[int(end2) + 1] - points[int(end2)]) segment2 = np.vstack( [start_point2, segment_point2s, end_point2]) directions = np.vstack([ start_point1 - segment2, segment1 - end_point2]) lines.append(directions) sphere_lines = [] for i, line in enumerate(lines): radii = np.sqrt(np.sum(line**2, axis=1)) thetas = np.arccos(line[:, 2] / radii) phis = np.arctan2(line[:, 1], line[:, 0]) local_radius = radius - 0.02*i*radius*np.sin(2*np.sin(thetas)) sphere_points = np.zeros(line.shape) sphere_points[:, 0] = radius * np.sin(thetas) * np.cos(phis) sphere_points[:, 1] = radius * np.sin(thetas) * np.sin(phis) sphere_points[:, 2] = radius * np.cos(thetas) # sphere_points += 2*(np.random.random(sphere_points.shape) - 0.5) * 0.005 * radius sphere_lines.append(sphere_points) self.plot(tube_radius=0.1, colour=(0.3, 0.3, 0.3, 1)) # Plot the poles from vispy.geometry import create_sphere from vispy.scene import Mesh meshdata = create_sphere(radius=0.035 * radius) vertices = meshdata.get_vertices() faces = meshdata.get_faces() vertices[:, 2] += radius mesh1 = Mesh(vertices=vertices, faces=faces, vertex_colors=np.array([(0.3, 0.3, 0.3, 1) for v in vertices])) vertices = vertices.copy() vertices[:, 2] -= 2*radius mesh2 = Mesh(vertices=vertices, faces=faces, vertex_colors=np.array([(0.3, 0.3, 0.3, 1) for v in vertices])) import pyknotid.visualise as pvis pvis.vispy_canvas.view.add(mesh1) pvis.vispy_canvas.view.add(mesh2) from colorsys import hsv_to_rgb colours = [hsv_to_rgb(hue, 1, 0.8) for hue in np.linspace(0, 1, len(sphere_lines) + 1)][:-1] colours = np.array(colours) np.random.shuffle(colours) for line, colour in zip(sphere_lines, colours): from pyknotid.spacecurves.openknot import OpenKnot k = OpenKnot(line) k.plot(clf=False, tube_radius=0.15, colour=colour, zero_centroid=False)
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 550)) self.meshes = [] self.rotation = MatrixTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color self.meshes.append(visuals.MeshVisual(meshdata=mdata, color='b')) # Mesh with pre-indexed vertices, per-face color # Because vertices are pre-indexed, we get a different color # every time a vertex is visited, resulting in sharp color # differences between edges. rng = np.random.RandomState(0) verts = mdata.get_vertices(indexed='faces') nf = verts.size//9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = rng.randn(nf, 1) fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = visuals.MeshVisual(vertices=verts, face_colors=fcolor) self.meshes.append(mesh) # Mesh with unindexed vertices, per-vertex color # Because vertices are unindexed, we get the same color # every time a vertex is visited, resulting in no color differences # between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size//3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = rng.randn(nv) vcolor[:, 2] = np.linspace(0, 1, nv) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor)) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='flat')) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor, shading='smooth')) # Mesh with color indexed into a colormap verts = mdata.get_vertices(None) faces = mdata.get_faces() values = rng.randn(len(verts)) mesh = visuals.MeshVisual(vertices=verts, faces=faces, vertex_values=values, shading='smooth') mesh.clim = [-1, 1] mesh.cmap = 'viridis' mesh.shininess = 0.01 self.meshes.append(mesh) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, s)), self.rotation]) mesh.transform = transform mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01)) self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
def skeleton2vispy(neuron, neuron_color, object_id, **kwargs): """Convert skeleton (i.e. TreeNeuron) into vispy visuals.""" visuals = [] if not kwargs.get('connectors_only', False) and not neuron.nodes.empty: # Make sure we have one color for each node neuron_color = np.asarray(neuron_color) if neuron_color.ndim == 1: neuron_color = np.tile(neuron_color, (neuron.nodes.shape[0], 1)) # Get nodes non_roots = neuron.nodes[neuron.nodes.parent_id >= 0] connect = np.zeros((non_roots.shape[0], 2), dtype=int) node_ix = pd.Series(np.arange(neuron.nodes.shape[0]), index=neuron.nodes.node_id.values) connect[:, 0] = node_ix.loc[non_roots.node_id].values connect[:, 1] = node_ix.loc[non_roots.parent_id].values # Create line plot from segments. t = scene.visuals.Line( pos=neuron.nodes[['x', 'y', 'z']].values, color=neuron_color, # Can only be used with method 'agg' width=kwargs.get('linewidth', 1), connect=connect, antialias=True, method='gl') # method can also be 'agg' -> has to use connect='strip' # Make visual discoverable t.interactive = True # Add custom attributes t.unfreeze() t._object_type = 'neuron' t._neuron_part = 'neurites' t._id = neuron.id t._name = str(getattr(neuron, 'name', neuron.id)) t._object = neuron t._object_id = object_id t.freeze() visuals.append(t) # Extract and plot soma soma = utils.make_iterable(neuron.soma) if kwargs.get('soma', True) and any(soma): # If soma detection is messed up we might end up producing # hundrets of soma which will freeze the session if len(soma) >= 10: logger.warning( f'Neuron {neuron.id} appears to have {len(soma)}' 'somas. That does not look right - will ignore ' 'them for plotting.') else: for s in soma: # If we have colors for every vertex, we need to find the # color that corresponds to this root (or it's parent to be # precise) if isinstance(neuron_color, np.ndarray) and neuron_color.ndim > 1: s_ix = np.where(neuron.nodes.node_id == s)[0][0] soma_color = neuron_color[s_ix] else: soma_color = neuron_color n = neuron.nodes.set_index('node_id').loc[s] r = getattr(n, neuron.soma_radius) if isinstance( neuron.soma_radius, str) else neuron.soma_radius sp = create_sphere(7, 7, radius=r) verts = sp.get_vertices() + n[['x', 'y', 'z']].values s = scene.visuals.Mesh(vertices=verts, shading='smooth', faces=sp.get_faces(), color=soma_color) s.ambient_light_color = vispy.color.Color('white') # Make visual discoverable s.interactive = True # Add custom attributes s.unfreeze() s._object_type = 'neuron' s._neuron_part = 'soma' s._id = neuron.id s._name = str(getattr(neuron, 'name', neuron.id)) s._object = neuron s._object_id = object_id s.freeze() visuals.append(s) return visuals
def create_border_cell(self): mdata = geometry.create_sphere(64, 64, radius=15) borders = scene.visuals.Mesh(meshdata=mdata, shading='flat', color="#f5f5f527") self.view.add(borders)
def __init__(self): self.meshes = [] self.rotation = AffineTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color verts = mdata.get_vertices(indexed='faces') mesh = ModularMesh(pos=verts, color=(1, 0, 0, 1)) self.meshes.append(mesh) # Mesh with pre-indexed vertices, per-face color # Because vertices are pre-indexed, we get a different color # every time a vertex is visited, resulting in sharp color # differences between edges. nf = verts.size//9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = np.random.normal(size=nf)[:, np.newaxis] fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = ModularMesh(pos=verts, color=fcolor) self.meshes.append(mesh) # Mesh with unindexed vertices, per-vertex color # Because vertices are unindexed, we get the same color # every time a vertex is visited, resulting in no color differences # between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size//3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = np.random.normal(size=nv) vcolor[:, 2] = np.linspace(0, 1, nv) mesh = ModularMesh(pos=verts, faces=faces, color=vcolor) self.meshes.append(mesh) # Mesh colored by vertices + grid contours mesh = ModularMesh(pos=verts, faces=faces) mesh.color_components = [VertexColorComponent(vcolor), GridContourComponent(spacing=(0.13, 0.13, 0.13))] self.meshes.append(mesh) # Phong shaded mesh mesh = ModularMesh(pos=verts, faces=faces) normal_comp = VertexNormalComponent(mdata) mesh.color_components = [VertexColorComponent(vcolor), GridContourComponent(spacing=(0.1, 0.1, 0.1)), ShadingComponent(normal_comp, lights=[((-1, 1, -1), (1.0, 1.0, 1.0))], ambient=0.2)] self.meshes.append(mesh) # Phong shaded mesh, flat faces mesh = ModularMesh(pos=mdata.get_vertices(indexed='faces')) normal_comp = VertexNormalComponent(mdata, smooth=False) mesh.color_components = [ VertexColorComponent(vcolor[mdata.get_faces()]), GridContourComponent(spacing=(0.1, 0.1, 0.1)), ShadingComponent(normal_comp, lights=[((-1, 1, -1), (1.0, 1.0, 1.0))], ambient=0.2)] self.meshes.append(mesh) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 mesh.transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, 1)), self.rotation]) vispy.scene.SceneCanvas.__init__(self, keys='interactive') self.size = (800, 800) self.show() self.timer = vispy.app.Timer(connect=self.rotate) self.timer.start(0.016)
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 550)) self.meshes = [] self.rotation = MatrixTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) verts = mdata.get_vertices() faces = mdata.get_faces() gamma, phi = xyz_to_gp(verts) data = np.cos(5*gamma)+np.cos(phi*4)/2. mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=False, nband=8, vertex_values=data) mesh.cmap = 'viridis' self.meshes.append(mesh) mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=True, nband=8, vertex_values=data) mesh.cmap = 'viridis' self.meshes.append(mesh) mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=False, nband=8, vertex_values=data, shading='flat') mesh.cmap = 'viridis' self.meshes.append(mesh) mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=True, nband=8, vertex_values=data, shading='flat') mesh.cmap = 'viridis' self.meshes.append(mesh) mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=False, nband=8, vertex_values=data, shading='smooth') mesh.cmap = 'viridis' mesh.shininess = 0.01 self.meshes.append(mesh) # Mesh with color indexed into a colormap mesh = visuals.MeshVisual(vertices=verts, faces=faces, banded=True, nband=8, vertex_values=data, shading='smooth') mesh.cmap = 'viridis' mesh.shininess = 0.01 self.meshes.append(mesh) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 transform = ChainTransform([STTransform(translate=(x, y), scale=(s, s, s)), self.rotation]) mesh.transform = transform mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01)) self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
labels_layer = viewer.add_labels( labeled, name='labels', blending='translucent', experimental_clipping_planes=[plane_parameters], ) # POINTS points_layer = viewer.add_points( np.random.rand(20, 3) * 64, size=5, experimental_clipping_planes=[plane_parameters], ) # SPHERE mesh = create_sphere(method='ico') sphere_vert = mesh.get_vertices() * 20 sphere_vert += 32 surface_layer = viewer.add_surface( (sphere_vert, mesh.get_faces()), experimental_clipping_planes=[plane_parameters], ) # SHAPES shapes_data = np.random.rand(3, 4, 3) * 64 shapes_layer = viewer.add_shapes( shapes_data, face_color=['magenta', 'green', 'blue'], experimental_clipping_planes=[plane_parameters], )
def test_sphere(): """Test sphere function""" md = create_sphere(10, 20, radius=10) radii = np.sqrt((md.get_vertices() ** 2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10)
def test_sphere(): """Test sphere function""" md = create_sphere(10, 20, radius=10) radii = np.sqrt((md.get_vertices()**2).sum(axis=1)) assert_allclose(radii, np.ones_like(radii) * 10)
def __init__(self): app.Canvas.__init__(self, keys='interactive', size=(800, 550)) self.meshes = [] self.rotation = MatrixTransform() # Generate some data to work with global mdata mdata = create_sphere(20, 40, 1.0) # Mesh with pre-indexed vertices, uniform color self.meshes.append(visuals.MeshVisual(meshdata=mdata, color='b')) # Mesh with pre-indexed vertices, per-face color # Because vertices are pre-indexed, we get a different color # every time a vertex is visited, resulting in sharp color # differences between edges. rng = np.random.RandomState(0) verts = mdata.get_vertices(indexed='faces') nf = verts.size // 9 fcolor = np.ones((nf, 3, 4), dtype=np.float32) fcolor[..., 0] = np.linspace(1, 0, nf)[:, np.newaxis] fcolor[..., 1] = rng.randn(nf, 1) fcolor[..., 2] = np.linspace(0, 1, nf)[:, np.newaxis] mesh = visuals.MeshVisual(vertices=verts, face_colors=fcolor) self.meshes.append(mesh) # Mesh with unindexed vertices, per-vertex color # Because vertices are unindexed, we get the same color # every time a vertex is visited, resulting in no color differences # between edges. verts = mdata.get_vertices() faces = mdata.get_faces() nv = verts.size // 3 vcolor = np.ones((nv, 4), dtype=np.float32) vcolor[:, 0] = np.linspace(1, 0, nv) vcolor[:, 1] = rng.randn(nv) vcolor[:, 2] = np.linspace(0, 1, nv) self.meshes.append(visuals.MeshVisual(verts, faces, vcolor)) self.meshes.append( visuals.MeshVisual(verts, faces, vcolor, shading='flat')) self.meshes.append( visuals.MeshVisual(verts, faces, vcolor, shading='smooth')) # Mesh with color indexed into a colormap verts = mdata.get_vertices(None) faces = mdata.get_faces() values = rng.randn(len(verts)) mesh = visuals.MeshVisual(vertices=verts, faces=faces, vertex_values=values, shading='smooth') mesh.clim = [-1, 1] mesh.cmap = 'viridis' mesh.shininess = 0.01 self.meshes.append(mesh) # Lay out meshes in a grid grid = (3, 3) s = 300. / max(grid) for i, mesh in enumerate(self.meshes): x = 800. * (i % grid[0]) / grid[0] + 400. / grid[0] - 2 y = 800. * (i // grid[1]) / grid[1] + 400. / grid[1] + 2 transform = ChainTransform([ STTransform(translate=(x, y), scale=(s, s, s)), self.rotation ]) mesh.transform = transform mesh.transforms.scene_transform = STTransform(scale=(1, 1, 0.01)) self.show() self.timer = app.Timer(connect=self.rotate) self.timer.start(0.016)
def __init__(self): GpaphicBlueprint.__init__(self) self.kind = 'sphere' oldMesh = create_sphere(10, 20) self._mesh = Mesh(oldMesh.get_vertices(), oldMesh.get_faces()) self.buildProgram()
def skeleton2vispy(neuron, neuron_color, object_id, **kwargs): """Convert skeleton (i.e. TreeNeuron) into vispy visuals.""" visuals = [] if not kwargs.get('connectors_only', False) and not neuron.nodes.empty: # Get root node indices (may be more than one if neuron has been # cut weirdly) root_ix = neuron.nodes[neuron.nodes.parent_id < 0].index.tolist() # Get nodes nodes = neuron.nodes[neuron.nodes.parent_id >= 0] # Extract treenode_coordinates and their parent's coordinates tn_coords = nodes[['x', 'y', 'z']].apply(pd.to_numeric).values parent_coords = neuron.nodes.set_index('node_id').loc[ nodes.parent_id.values][['x', 'y', 'z']].apply(pd.to_numeric).values # Add alpha to color based on strahler if kwargs.get('by_strahler', False) \ or kwargs.get('by_confidence', False): if kwargs.get('by_strahler', False): if 'strahler_index' not in neuron.nodes: morpho.strahler_index(neuron) # Generate list of alpha values alpha = neuron.nodes['strahler_index'].values if kwargs.get('by_confidence', False): if 'arbor_confidence' not in neuron.nodes: morpho.arbor_confidence(neuron) # Generate list of alpha values alpha = neuron.nodes['arbor_confidence'].values # Pop root from coordinate lists alpha = np.delete(alpha, root_ix, axis=0) alpha = alpha / (max(alpha) + 1) # Duplicate values (start and end of each segment!) alpha = np.array([v for l in zip(alpha, alpha) for v in l]) # Turn color into array # (need 2 colors per segment for beginning and end) neuron_color = np.array([neuron_color] * (tn_coords.shape[0] * 2), dtype=float) neuron_color = np.insert(neuron_color, 3, alpha, axis=1) if not kwargs.get('radius', False): # Turn coordinates into segments segments = [ item for sublist in zip(tn_coords, parent_coords) for item in sublist ] # Create line plot from segments. t = scene.visuals.Line( pos=np.array(segments), color=list(neuron_color), # Can only be used with method 'agg' width=kwargs.get('linewidth', 1), connect='segments', antialias=True, method='gl') # method can also be 'agg' -> has to use connect='strip' # Make visual discoverable t.interactive = True # Add custom attributes t.unfreeze() t._object_type = 'neuron' t._neuron_part = 'neurites' t._id = neuron.id t._name = str(getattr(neuron, 'name', neuron.id)) t._object_id = object_id t.freeze() visuals.append(t) else: # Generate coordinates coords = segments_to_coords(neuron, neuron.segments, modifier=(1, 1, 1)) # For each point of each segment get the radius nodes = neuron.nodes.set_index('node_id') radii = [ nodes.loc[s, 'radius'].values.astype(float) for s in neuron.segments ] # Generate faces and vertices for the tube verts, faces = make_tube(segments=coords, radii=radii, use_normals=kwargs.get( 'use_normals', True), tube_points=kwargs.get('tube_points', 3)) vertex_colors = np.resize( neuron_color, (verts.shape[0], kwargs.get('tube_points', 3))) t = scene.visuals.Mesh(vertices=verts, faces=faces, vertex_colors=vertex_colors, shading='smooth', mode='triangles') # Add custom attributes t.unfreeze() t._object_type = 'neuron' t._neuron_part = 'neurites' t._id = neuron.id t._name = str(getattr(neuron, 'name', neuron.id)) t._object_id = object_id t.freeze() visuals.append(t) if kwargs.get('by_strahler', False) or \ kwargs.get('by_confidence', False): # Convert array back to a single color without alpha neuron_color = neuron_color[0][:3] # Extract and plot soma soma = utils.make_iterable(neuron.soma) if any(soma): # If soma detection is messed up we might end up producing # dozens of soma which will freeze the kernel if len(soma) >= 10: logger.warning(f'{neuron.id}: {len(soma)} somas found.') for s in soma: n = neuron.nodes.set_index('node_id').loc[s] r = getattr(n, neuron.soma_radius) if isinstance( neuron.soma_radius, str) else neuron.soma_radius sp = create_sphere(7, 7, radius=r) verts = sp.get_vertices() + n[['x', 'y', 'z']].values s = scene.visuals.Mesh(vertices=verts, shading='smooth', faces=sp.get_faces(), color=neuron_color) s.ambient_light_color = vispy.color.Color('white') # Make visual discoverable s.interactive = True # Add custom attributes s.unfreeze() s._object_type = 'neuron' s._neuron_part = 'soma' s._id = neuron.id s._name = str(getattr(neuron, 'name', neuron.id)) s._object_id = object_id s.freeze() visuals.append(s) return visuals
def update(self, t, crazyflies): if len(self.cfs) == 0: verts, faces, normals, nothin = io.read_mesh(CF_MESH_PATH) for i, cf in enumerate(crazyflies): color = cf.ledRGB mesh = scene.visuals.Mesh( parent=self.view.scene, vertices=verts, faces=faces, color=color, shading="smooth", ) mesh.light_dir = (0.1, 0.1, 1.0) mesh.shininess = 0.01 mesh.ambient_light_color = [0.5] * 3 mesh.transform = transforms.MatrixTransform() self.cfs.append(mesh) self.led_color_cache.append(color) if self.ellipsoid_radii is not None and self.ellipsoids is None: sphere_mesh = geometry.create_sphere(radius=1.0) self.ellipsoids = [ scene.visuals.Mesh( parent=self.view.scene, meshdata=sphere_mesh, color=ELLIPSOID_COLOR_OK, shading="smooth", ) for _ in self.cfs ] for ell in self.ellipsoids: ell.light_dir = (0.1, 0.1, 1.0) ell.shininess = 0.0 ell.ambient_light_color = [0.5] * 3 ell.transform = transforms.MatrixTransform() positions = np.stack([cf.position() for cf in crazyflies]) for i in range(0, len(self.cfs)): x, y, z = crazyflies[i].position() roll, pitch, yaw = crazyflies[i].rpy() self.cfs[i].transform.reset() self.cfs[i].transform.rotate(-90, (1, 0, 0)) self.cfs[i].transform.rotate(math.degrees(roll), (1, 0, 0)) self.cfs[i].transform.rotate(math.degrees(pitch), (0, 1, 0)) self.cfs[i].transform.rotate(math.degrees(yaw), (0, 0, 1)) self.cfs[i].transform.scale((0.002, 0.002, -0.002)) self.cfs[i].transform.translate(positions[i]) # vispy does not do this check color = crazyflies[i].ledRGB if color != self.led_color_cache[i]: self.led_color_cache[i] = color self.cfs[i].color = color # sets dirty flag # Update graph line segments to match new Crazyflie positions. if self.graph is not None: for k, (i, j) in enumerate(self.graph_edges): self.graph_lines[2 * k, :] = positions[i] self.graph_lines[2 * k + 1, :] = positions[j] self.graph.set_data(self.graph_lines) # Update collsiion ellipsoids. if self.ellipsoids is not None: colliding = util.check_ellipsoid_collisions( positions, self.ellipsoid_radii) for i, pos in enumerate(positions): ell = self.ellipsoids[i] tf = ell.transform tf.reset() tf.scale(self.ellipsoid_radii) tf.translate(pos) new_color = ELLIPSOID_COLOR_COLLISION if colliding[ i] else ELLIPSOID_COLOR_OK if not (new_color == ell.color): # vispy Color lacks != override. ell.color = new_color self.canvas.app.process_events()
def dotprop2vispy(x, **kwargs): """Converts dotprops(s) to vispy visuals. Parameters ---------- x : core.Dotprops | pd.DataFrame Dotprop(s) to plot. colormap : tuple | dict | array Color to use for plotting. Dictionaries should be mapped to gene names. scale_vect : int, optional Vector to scale dotprops by. Returns ------- list Contains vispy visuals for each dotprop. """ if not isinstance(x, (core.Dotprops, pd.DataFrame)): raise TypeError(f'Unable to process data of type "{type(x)}"') visuals = [] # Parse colors for dotprops colors = kwargs.get('color', kwargs.get('c', kwargs.get('colors', None))) _, colormap, _ = prepare_colormap(colors, dotprops=x, use_neuron_color=False, color_range=1) scale_vect = kwargs.get('scale_vect', 1) for i, n in enumerate(x.itertuples()): # Generate random ID -> we need this in case we have duplicate IDs object_id = uuid.uuid4() color = colormap[i] # Prepare lines - this is based on nat:::plot3d.dotprops halfvect = n.points[['x_vec', 'y_vec', 'z_vec']] / 2 * scale_vect starts = n.points[['x', 'y', 'z']].values - halfvect.values ends = n.points[['x', 'y', 'z']].values + halfvect.values segments = [item for sublist in zip(starts, ends) for item in sublist] t = scene.visuals.Line(pos=np.array(segments), color=color, width=2, connect='segments', antialias=False, method='gl') # method can also be 'agg' # Add custom attributes t.unfreeze() t._object_type = 'dotprop' t._neuron_part = 'neurites' t._name = getattr(n, 'gene_name', getattr(n, 'name', 'NoName')) t._object_id = object_id t.freeze() visuals.append(t) # Add soma (if provided as X/Y/Z) if all([hasattr(n, v) for v in ['X', 'Y', 'Z']]): sp = create_sphere(5, 5, radius=4) s = scene.visuals.Mesh(vertices=sp.get_vertices() + np.array([n.X, n.Y, n.Z]), faces=sp.get_faces(), color=color) # Add custom attributes s.unfreeze() s._object_type = 'dotprop' s._neuron_part = 'soma' s._name = n.gene_name s._object_id = object_id s.freeze() visuals.append(s) return visuals