def curve2mesh(crv, property=None): """Return a mesh from a curve""" d = Discretizer() indices, vertices, colors, attribute = [], [], [], [] colordict = {} count = -1 offset = 0 for obj in crv: status = obj.apply(d) pts = [(pt.x, pt.y, pt.z) for pt in list(d.result.pointList)] vertices.extend(pts) color = obj.appearance.ambient color = (color.red, color.green, color.blue) if color not in colordict: count += 1 colordict[color] = count offset += len(pts) attribute.extend([colordict[color]] * len(pts)) colors = np.array(list(colordict.keys())) / 255. if property is not None: property = np.repeat(np.array(property), [3] * len(property)) mesh = k3d.line(vertices, shader='mesh', attribute=property, color_map=k3d.basic_color_maps.Jet, color_range=[min(property), max(property)]) elif len(colors) == 1: colorhex = int(matplotlib.colors.rgb2hex(colors[0])[1:], 16) mesh = k3d.line(vertices, shader='mesh') mesh.color = colorhex else: color_map = list( zip( list( np.array(list(colordict.values())) / float(max(colordict.values()))), colors[:, 0], colors[:, 1], colors[:, 2])) color_map.sort() #color_map=k3d.basic_color_maps.Jet attribute = list(np.array(attribute) / float(max(attribute))) mesh = k3d.line(vertices, shader='mesh', attribute=attribute, color_map=color_map) return mesh
def __init__(self, function, phi, domain=10, **kwds): self.function = function self.phi = phi self.domain = domain # pass along named parameters, like e.g. height super().__init__(**kwds) # returns the format expected by k3d line dots, center = self.compute_dots_and_center() # create line and add in plot self.line = k3d.line(dots) self += self.line # the line that materializes the barycenter self.center_line = k3d.line(center, color=0xff0000, width=0.5) self += self.center_line
def __get_joint_lines(self) -> List[Line]: skeleton_line_colors: np.ndarray = self.__get_line_colors() return [ k3d.line(vertices=[ self.joint_positions[self.joint_set.limb_graph[line_index][0]], self.joint_positions[self.joint_set.limb_graph[line_index][1]] ], width=self.part_size / 2.2, color=int(skeleton_line_colors[line_index]), shader='mesh') for line_index in range(len(self.joint_set.limb_graph)) ]
def new_plot(self, bs=1.0): points_number = 1 positions = 50 * np.random.random_sample((points_number, 3)) - 25 colors = np.random.randint(0, 0x777777, points_number) self.plot = k3d.plot() self.pkts = k3d.points(positions, colors, point_size=.3) self.plot += self.pkts self.plot.camera_auto_fit = False self.plot.grid_auto_fit = False self.box = k3d.line(self.box_coords(bs=bs)) self.plot += self.box
def plot_simulation_box(box,**kwargs): kwargs.setdefault('shader','simple') a=[2*box[3],0,0] if len(box)==9: b=[box[6],2*box[4],0] c=[box[7],box[8],2*box[5]] else: b=[0,2*box[4],0] c=[0,0,2*box[5]] origin=np.array([box[0],box[1],box[2]]) a=np.array(a) b=np.array(b) c=np.array(c) f1=[origin,origin+a,origin+a+b,origin+b,origin] f2=[origin+c,origin+a+c,origin+a+b+c,origin+b+c,origin+c] c1=[origin,origin+c] c2=[origin+a,origin+a+c] c3=[origin+a+b,origin+a+b+c] c4=[origin+b,origin+b+c] line = k3d.line(f1,**kwargs) for l in f2,c1,c2,c3,c4: line += k3d.line(l,**kwargs) return line
def __get_joint_lines_for_video(self) -> List[Line]: skeleton_line_colors: np.ndarray = self.__get_line_colors() return [ k3d.line(vertices={ current_timestamp[0]: np.array([ current_timestamp[1][self.joint_set.limb_graph[line_index] [0]], current_timestamp[1] [self.joint_set.limb_graph[line_index][1]] ]) for current_timestamp in self.joint_positions.items() }, width=self.part_size / 2.2, color=int(skeleton_line_colors[line_index]), shader='mesh') for line_index in range(len(self.joint_set.limb_graph)) ]
def display_3d(K,show_labels=False): """display a 3d simplicial complex using k3d, in jupyter to install it: sudo pip install k3d sudo jupyter nbextension install --py k3d sudo jupyter nbextension enable --py k3d """ import k3d if not isinstance(K.vertices[0] ,Point): raise Exception("Can display only Point-class vertices of dim 3!!!") dim=K.vertices[0].dim if dim != 3: sys.stderr.write("Not yet implemented display in dim = %s\n" % dim ) return None vertices = [v.coords for v in K.vertices] edges = [ s for s in K.simplices[1] ] faces = [] if 2 in K.simplices: faces = [ s for s in K.simplices[2] ] plt=k3d.plot(name='points') plt_points = k3d.points( positions=vertices , point_size=0.05) plt_points.shader ='3dSpecular' plt_points.color = 14 plt += plt_points # now lines: for s in edges: plt_line = k3d.line([vertices[s[0]],vertices[s[1]] ],shader='mesh', width=0.01, color=0xff0000) plt += plt_line # now convert all faces to a mesh plt_mesh = k3d.mesh(vertices,faces,color=0xff, wireframe=False, opacity=0.7, name="Simplicial Complex") plt += plt_mesh # now add the text for P in K.vertices: if show_labels and P.label is not None: plt_text = k3d.text("%s" % repr(P), position = P.coords, color=0x7700,size=1) plt += plt_text #finally display plt.display()
def tomesh(geometry, d=None): """Return a mesh from a geometry object""" isCurve = False if geometry.isACurve(): isCurve = True if d is None: d = Tesselator() if not isCurve else Discretizer() geometry.apply(d) if isCurve: pts = [(pt.x, pt.y, pt.z) for pt in list(d.result.pointList)] mesh = k3d.line(pts, shader='mesh') else: idl = [tuple(index) for index in list(d.discretization.indexList)] pts = [(pt.x, pt.y, pt.z) for pt in list(d.discretization.pointList)] mesh = k3d.mesh(vertices=pts, indices=idl) return mesh
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance #################################################################################### # https://github.com/InsightSoftwareConsortium/itkwidgets # /blob/master/itkwidgets/widget_viewer.py if 'itk' in settings.notebookBackend: from itkwidgets import view if sum(vp.shape) != 2: colors.printc("Warning: multirendering is not supported in jupyter.", c=1) settings.notebook_plotter = view(actors=actors2show, cmap='jet', ui_collapsed=True, gradient_opacity=False) #################################################################################### elif settings.notebookBackend == 'k3d': import k3d # https://github.com/K3D-tools/K3D-jupyter if vp.shape[0] != 1 or vp.shape[1] != 1: colors.printc("Warning: multirendering is not supported in jupyter.", c=1) actors2show2 = [] for ia in actors2show: if isinstance(ia, vtk.vtkAssembly): #unpack assemblies acass = ia.unpack() #for a in acass: # a.SetScale(ia.GetScale()) actors2show2 += acass else: actors2show2.append(ia) vbb, sizes, min_bns, max_bns = addons.computeVisibleBounds() kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=True, height=int(vp.size[1]/2) ) settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = 1.2 # set k3d camera settings.notebook_plotter.camera_auto_fit = False eps = 1 + numpy.random.random()*1.0e-04 # workaround to bug in k3d # https://github.com/K3D-tools/K3D-jupyter/issues/180 if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) k3dc[2] = k3dc[2]*eps settings.notebook_plotter.camera = k3dc else: vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] vss = numpy.linalg.norm([vsx, vsy, vsz]) if zoom: vss /= zoom vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target if viewup == 'z': vup = (0,0,1) # camera up vector vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position elif viewup == 'x': vup = (1,0,0) vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position else: vup = (0,1,0) vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2]*eps, vfp[0], vfp[1], vfp[2], vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False for ia in actors2show2: kobj = None kcmap= None if isinstance(ia, Mesh) and ia.N(): iap = ia.GetProperty() #ia.clean().triangulate().computeNormals() #ia.triangulate()) iapoly = ia.clone().clean().triangulate().computeNormals().polydata() vtkscals = None color_attribute = None if ia.mapper().GetScalarVisibility(): vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is None: vtkdata = iapoly.GetCellData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(iapoly) c2p.Update() iapoly = c2p.GetOutput() vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: if not vtkscals.GetName(): vtkscals.SetName('scalars') scals_min, scals_max = ia.mapper().GetScalarRange() color_attribute = (vtkscals.GetName(), scals_min, scals_max) lut = ia.mapper().GetLookupTable() lut.Build() kcmap=[] nlut = lut.GetNumberOfTableValues() for i in range(nlut): r,g,b,a = lut.GetTableValue(i) kcmap += [i/(nlut-1), r,g,b] if iapoly.GetNumberOfPolys() > 0: name = None if ia.filename: name = os.path.basename(ia.filename) kobj = k3d.vtk_poly_data(iapoly, name=name, color=colors.rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), wireframe=(iap.GetRepresentation()==1)) if iap.GetInterpolation() == 0: kobj.flat_shading = True else: kcols=[] if color_attribute is not None: scals = vtk_to_numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) if ia.NPoints() == ia.NCells(): kobj = k3d.points(ia.points().astype(numpy.float32), color=colors.rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader="3d", point_size=iap.GetPointSize()*sqsize/400, #compression_level=9, ) else: kobj = k3d.line(ia.points().astype(numpy.float32), color=colors.rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader="thick", width=iap.GetLineWidth()*sqsize/1000, ) settings.notebook_plotter += kobj elif isinstance(ia, Volume): kx, ky, kz = ia.dimensions() arr = ia.getPointArray() kimage = arr.reshape(-1, ky, kx) colorTransferFunction = ia.GetProperty().GetRGBTransferFunction() kcmap=[] for i in range(128): r,g,b = colorTransferFunction.GetColor(i/127) kcmap += [i/127, r,g,b] #print('vol scal range', ia.imagedata().GetScalarRange()) #print(numpy.min(kimage), numpy.max(kimage)) kbounds = numpy.array(ia.imagedata().GetBounds()) \ + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\ * numpy.array([-1,1] * 3) kobj = k3d.volume(kimage.astype(numpy.float32), color_map=kcmap, #color_range=ia.imagedata().GetScalarRange(), alpha_coef=10, bounds=kbounds, ) settings.notebook_plotter += kobj elif hasattr(ia, 'info') and 'formula' in ia.info.keys(): pos = (ia.GetPosition()[0],ia.GetPosition()[1]) kobj = k3d.text2d(ia.info['formula'], position=pos) settings.notebook_plotter += kobj #################################################################################### elif settings.notebookBackend == 'panel' and hasattr(vp, 'window') and vp.window: import panel # https://panel.pyviz.org/reference/panes/VTK.html vp.renderer.ResetCamera() settings.notebook_plotter = panel.pane.VTK(vp.window, width=int(vp.size[0]/1.5), height=int(vp.size[1]/2)) #################################################################################### elif '2d' in settings.notebookBackend.lower() and hasattr(vp, 'window') and vp.window: import PIL.Image try: import IPython except ImportError: raise Exception('IPython not available.') return from vtkplotter.vtkio import screenshot settings.screeshotLargeImage = True nn = screenshot(returnNumpy=True, scale=settings.screeshotScale+2) pil_img = PIL.Image.fromarray(nn) settings.notebook_plotter = IPython.display.display(pil_img) return settings.notebook_plotter
def __init__( self, lcs: LocalCoordinateSystem, plot: k3d.Plot = None, name: str = None, color: int = RGB_BLACK, show_origin=True, show_trace=True, show_vectors=True, vector_scale=2.5, ): """Create a `CoordinateSystemVisualizerK3D`. Parameters ---------- lcs : Coordinate system that should be visualized plot : A k3d plotting widget. name : Name of the coordinate system color : The RGB color of the coordinate system (affects trace and label) as a 24 bit integer value. show_origin : If `True`, the origin of the coordinate system will be highlighted in the color passed as another parameter show_trace : If `True`, the trace of a time dependent coordinate system will be visualized in the color passed as another parameter show_vectors : If `True`, the the coordinate axes of the coordinate system are visualized """ coordinates, orientation = _get_coordinates_and_orientation(lcs) self._lcs = lcs self._color = color self._vector_scale = vector_scale self._vectors = k3d.vectors( origins=[coordinates for _ in range(3)], vectors=orientation.transpose() * self._vector_scale, line_width=0.05, head_size=3.0, colors=[[RGB_RED, RGB_RED], [RGB_GREEN, RGB_GREEN], [RGB_BLUE, RGB_BLUE]], labels=[], label_size=1.5, name=name if name is None else f"{name} (vectors)", ) self._vectors.visible = show_vectors self._label = None if name is not None: self._label = k3d.text( text=name, position=coordinates + 0.05, color=self._color, size=1, label_box=False, name=name if name is None else f"{name} (text)", ) self._trace = k3d.line( _get_unitless_coordinates(lcs), # type: ignore shader="thick", width=0.1, # change with .set_trait("width", value) color=color, name=name if name is None else f"{name} (line)", ) self._trace.visible = show_trace self.origin = platonic.Octahedron(size=0.1).mesh self.origin.color = color self.origin.model_matrix = _create_model_matrix(coordinates, orientation) self.origin.visible = show_origin if plot is not None: plot += self._vectors plot += self._trace plot += self.origin if self._label is not None: plot += self._label
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance if zoom == 'tight': zoom=1 # disable it if isinstance(vp.shape, str) or sum(vp.shape) > 2: colors.printc("Multirendering is not supported in jupyter.", c=1) return #################################################################################### # https://github.com/InsightSoftwareConsortium/itkwidgets # /blob/master/itkwidgets/widget_viewer.py if 'itk' in settings.notebookBackend: from itkwidgets import view settings.notebook_plotter = view(actors=actors2show, cmap='jet', ui_collapsed=True, gradient_opacity=False) #################################################################################### elif settings.notebookBackend == 'k3d': try: import k3d # https://github.com/K3D-tools/K3D-jupyter except: print("Cannot find k3d, install with: pip install k3d") return actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vtk.vtkAssembly): #unpack assemblies acass = ia.unpack() actors2show2 += acass else: actors2show2.append(ia) # vbb, sizes, _, _ = addons.computeVisibleBounds() # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=settings.k3dMenuVisibility, height=settings.k3dPlotHeight, antialias=settings.k3dAntialias, ) # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = settings.k3dLighting # set k3d camera settings.notebook_plotter.camera_auto_fit = settings.k3dCameraAutoFit settings.notebook_plotter.grid_auto_fit = settings.k3dGridAutoFit settings.notebook_plotter.axes_helper = settings.k3dAxesHelper if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) if zoom: k3dc[0] /= zoom k3dc[1] /= zoom k3dc[2] /= zoom settings.notebook_plotter.camera = k3dc # else: # vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] # vss = numpy.linalg.norm([vsx, vsy, vsz]) # if zoom: # vss /= zoom # vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target # if viewup == 'z': # vup = (0,0,1) # camera up vector # vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position # elif viewup == 'x': # vup = (1,0,0) # vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position # else: # vup = (0,1,0) # vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position # settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], # vfp[0], vfp[1], vfp[2], # vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False for ia in actors2show2: if isinstance(ia, (vtk.vtkCornerAnnotation, vtk.vtkAssembly)): continue kobj = None kcmap= None name = None if hasattr(ia, 'filename'): if ia.filename: name = os.path.basename(ia.filename) if ia.name: name = os.path.basename(ia.name) #####################################################################scalars # work out scalars first, Points Lines are also Mesh objs if isinstance(ia, (Mesh, shapes.Line, Points)): # print('scalars', ia.name, ia.N()) iap = ia.GetProperty() if isinstance(ia, (shapes.Line, Points)): iapoly = ia.polydata() else: iapoly = ia.clone().clean().triangulate().computeNormals().polydata() vtkscals = None color_attribute = None if ia.mapper().GetScalarVisibility(): vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is None: vtkdata = iapoly.GetCellData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(iapoly) c2p.Update() iapoly = c2p.GetOutput() vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: if not vtkscals.GetName(): vtkscals.SetName('scalars') scals_min, scals_max = ia.mapper().GetScalarRange() color_attribute = (vtkscals.GetName(), scals_min, scals_max) lut = ia.mapper().GetLookupTable() lut.Build() kcmap=[] nlut = lut.GetNumberOfTableValues() for i in range(nlut): r,g,b,a = lut.GetTableValue(i) kcmap += [i/(nlut-1), r,g,b] #####################################################################Volume if isinstance(ia, Volume): # print('Volume', ia.name, ia.dimensions()) kx, ky, kz = ia.dimensions() arr = ia.pointdata[0] kimage = arr.reshape(-1, ky, kx) colorTransferFunction = ia.GetProperty().GetRGBTransferFunction() kcmap=[] for i in range(128): r,g,b = colorTransferFunction.GetColor(i/127) kcmap += [i/127, r,g,b] kbounds = numpy.array(ia.imagedata().GetBounds()) \ + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\ * numpy.array([-1,1] * 3) kobj = k3d.volume(kimage.astype(numpy.float32), color_map=kcmap, #color_range=ia.imagedata().GetScalarRange(), alpha_coef=10, bounds=kbounds, name=name, ) settings.notebook_plotter += kobj #####################################################################text elif hasattr(ia, 'info') and 'formula' in ia.info.keys(): pos = (ia.GetPosition()[0],ia.GetPosition()[1]) kobj = k3d.text2d(ia.info['formula'], position=pos) settings.notebook_plotter += kobj #####################################################################Mesh elif isinstance(ia, Mesh) and ia.N() and len(ia.faces()): # print('Mesh', ia.name, ia.N(), len(ia.faces())) kobj = k3d.vtk_poly_data(iapoly, name=name, # color=_rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), wireframe=(iap.GetRepresentation()==1)) if iap.GetInterpolation() == 0: kobj.flat_shading = True settings.notebook_plotter += kobj #####################################################################Points elif isinstance(ia, Points): # print('Points', ia.name, ia.N()) kcols=[] if color_attribute is not None: scals = utils.vtk2numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) kobj = k3d.points(ia.points().astype(numpy.float32), color=_rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader=settings.k3dPointShader, point_size=iap.GetPointSize(), name=name, ) settings.notebook_plotter += kobj #####################################################################Lines elif ia.polydata(False).GetNumberOfLines(): # print('Line', ia.name, ia.N(), len(ia.faces()), # ia.polydata(False).GetNumberOfLines(), len(ia.lines()), # color_attribute, [vtkscals]) # kcols=[] # if color_attribute is not None: # scals = utils.vtk2numpy(vtkscals) # kcols = k3d.helpers.map_colors(scals, kcmap, # [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) for i, ln_idx in enumerate(ia.lines()): if i>200: print('WARNING: K3D nr of line segments is limited to 200.') break pts = ia.points()[ln_idx] kobj = k3d.line(pts.astype(numpy.float32), color=_rgb2int(iap.GetColor()), opacity=iap.GetOpacity(), shader=settings.k3dLineShader, # width=iap.GetLineWidth()*sqsize/1000, name=name, ) settings.notebook_plotter += kobj #################################################################################### elif settings.notebookBackend == 'panel' and hasattr(vp, 'window') and vp.window: import panel # https://panel.pyviz.org/reference/panes/VTK.html vp.renderer.ResetCamera() settings.notebook_plotter = panel.pane.VTK(vp.window, width=int(vp.size[0]/1.5), height=int(vp.size[1]/2)) #################################################################################### elif 'ipyvtk' in settings.notebookBackend and hasattr(vp, 'window') and vp.window: from ipyvtklink.viewer import ViewInteractiveWidget vp.renderer.ResetCamera() settings.notebook_plotter = ViewInteractiveWidget(vp.window) #################################################################################### elif 'ipygany' in settings.notebookBackend: from ipygany import PolyMesh, Scene, IsoColor, RGB, Component from ipygany import Alpha, ColorBar, colormaps, PointCloud from ipywidgets import FloatRangeSlider, Dropdown, VBox, AppLayout, jslink bgcol = colors.rgb2hex(colors.getColor(vp.backgrcol)) actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vedo.Assembly): #unpack assemblies assacts = ia.unpack() for ja in assacts: if isinstance(ja, vedo.Assembly): actors2show2 += ja.unpack() else: actors2show2.append(ja) else: actors2show2.append(ia) pmeshes = [] colorbar = None for obj in actors2show2: # print("ipygany processing:", [obj], obj.name) if isinstance(obj, vedo.shapes.Line): lg = obj.diagonalSize()/1000 * obj.GetProperty().GetLineWidth() vmesh = vedo.shapes.Tube(obj.points(), r=lg, res=4).triangulate() vmesh.c(obj.c()) faces = vmesh.faces() # todo: Lines elif isinstance(obj, Mesh): vmesh = obj.triangulate() faces = vmesh.faces() elif isinstance(obj, Points): vmesh = obj faces = [] elif isinstance(obj, Volume): vmesh = obj.isosurface() faces = vmesh.faces() elif isinstance(obj, vedo.TetMesh): vmesh = obj.tomesh(fill=False) faces = vmesh.faces() else: print("ipygany backend: cannot process object type", [obj]) continue vertices = vmesh.points() scals = vmesh.inputdata().GetPointData().GetScalars() if scals and not colorbar: # there is an active array, only pick the first aname = scals.GetName() arr = vmesh.pointdata[aname] parr = Component(name=aname, array=arr) if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces, data={aname: [parr]}) else: pmesh = PointCloud(vertices=vertices, data={aname: [parr]}) rng = scals.GetRange() colored_pmesh = IsoColor(pmesh, input=aname, min=rng[0], max=rng[1]) if obj.scalarbar: colorbar = ColorBar(colored_pmesh) colormap_slider_range = FloatRangeSlider(value=rng, min=rng[0], max=rng[1], step=(rng[1] - rng[0]) / 100.) jslink((colored_pmesh, 'range'), (colormap_slider_range, 'value')) colormap = Dropdown( options=colormaps, description='Colormap:' ) jslink((colored_pmesh, 'colormap'), (colormap, 'index')) else: if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces) else: pmesh = PointCloud(vertices=vertices) if vmesh.alpha() < 1: colored_pmesh = Alpha(RGB(pmesh, input=tuple(vmesh.color())), input=vmesh.alpha()) else: colored_pmesh = RGB(pmesh, input=tuple(vmesh.color())) pmeshes.append(colored_pmesh) if colorbar: scene = AppLayout( left_sidebar=Scene(pmeshes, background_color=bgcol), right_sidebar=VBox((colormap_slider_range, #not working colorbar, colormap)), pane_widths=[2, 0, 1], ) else: scene = Scene(pmeshes, background_color=bgcol) settings.notebook_plotter = scene #################################################################################### elif '2d' in settings.notebookBackend.lower() and hasattr(vp, 'window') and vp.window: import PIL.Image try: import IPython except ImportError: raise Exception('IPython not available.') from vedo.io import screenshot settings.screeshotLargeImage = True nn = screenshot(returnNumpy=True, scale=settings.screeshotScale+2) pil_img = PIL.Image.fromarray(nn) settings.notebook_plotter = IPython.display.display(pil_img) return settings.notebook_plotter
def neuron2k3d(x, colormap, **kwargs): """Convert neurons to k3d objects.""" if isinstance(x, core.BaseNeuron): x = core.NeuronList(x) elif not isinstance(x, core.NeuronList): raise TypeError('Unable to process data of type "{}"'.format(type(x))) palette = kwargs.get('palette', None) color_by = kwargs.get('color_by', None) shade_by = kwargs.get('shade_by', None) lg = kwargs.pop('legend_group', None) if not isinstance(color_by, type(None)): if not palette: raise ValueError('Must provide `palette` (e.g. "viridis") argument ' 'if using `color_by`') colormap = vertex_colors(x, by=color_by, alpha=kwargs.get('alpha', 1), use_alpha=False, palette=palette, vmin=kwargs.get('vmin', None), vmax=kwargs.get('vmax', None), na=kwargs.get('na', 'raise'), color_range=255) if not isinstance(shade_by, type(None)): logger.warning('`shade_by` does not work with the k3d backend') cn_lay = config.default_connector_colors.copy() cn_lay.update(kwargs.get('synapse_layout', {})) trace_data = [] for i, neuron in enumerate(x): name = str(getattr(neuron, 'name', neuron.id)) color = colormap[i] try: # Try converting this neuron's ID neuron_id = str(neuron.id) except BaseException: # If that doesn't work generate a new ID neuron_id = str(str(uuid.uuid1())) showlegend = True label = neuron.label if isinstance(lg, dict) and neuron.id in lg: # Check if this the first entry for this legendgroup label = legendgroup = lg[neuron.id] for d in trace_data: # If it is not the first entry, hide it if getattr(d, 'legendgroup', None) == legendgroup: showlegend = False break elif isinstance(lg, str): legendgroup = lg else: legendgroup = neuron_id if kwargs.get('radius', False): # Convert and carry connectors with us if isinstance(neuron, core.TreeNeuron): _neuron = conversion.tree2meshneuron(neuron) _neuron.connectors = neuron.connectors neuron = _neuron if not kwargs.get('connectors_only', False): if isinstance(neuron, core.TreeNeuron): trace_data += skeleton2k3d(neuron, label=label, legendgroup=legendgroup, showlegend=showlegend, color=color, **kwargs) elif isinstance(neuron, core.MeshNeuron): trace_data += mesh2k3d(neuron, label=label, legendgroup=legendgroup, showlegend=showlegend, color=color, **kwargs) elif isinstance(neuron, core.Dotprops): trace_data += dotprops2k3d(neuron, label=label, legendgroup=legendgroup, showlegend=showlegend, color=color, **kwargs) elif isinstance(neuron, core.VoxelNeuron): trace_data += voxel2k3d(neuron, label=label, legendgroup=legendgroup, showlegend=showlegend, color=color, **kwargs) else: raise TypeError(f'Unable to plot neurons of type "{type(neuron)}"') # Add connectors if (kwargs.get('connectors', False) or kwargs.get('connectors_only', False)) and neuron.has_connectors: cn_colors = kwargs.get('cn_colors', None) for j in neuron.connectors.type.unique(): if isinstance(cn_colors, dict): c = cn_colors.get(j, cn_lay.get(j, {'color': (10, 10, 10)})['color']) elif cn_colors == 'neuron': c = color elif cn_colors: c = cn_colors else: c = cn_lay.get(j, {'color': (10, 10, 10)})['color'] c = color_to_int(eval_color(c, color_range=255)) this_cn = neuron.connectors[neuron.connectors.type == j] cn_label = f'{cn_lay.get(j, {"name": "connector"})["name"]} of {name}' if cn_lay['display'] == 'circles' or not isinstance(neuron, core.TreeNeuron): with warnings.catch_warnings(): warnings.simplefilter("ignore") trace_data.append(k3d.points( positions=this_cn[['x', 'y', 'z']].values, name=cn_label, shader='flat', point_size=1000, color=c )) elif cn_lay['display'] == 'lines': # Find associated treenodes co1 = this_cn[['x', 'y', 'z']].values co2 = neuron.nodes.set_index('node_id').loc[this_cn.node_id.values, ['x', 'y', 'z']].values coords = np.array([co for seg in zip(co1, co1, co2, co2, [[np.nan] * 3] * len(co1)) for co in seg]) lw = kwargs.get('linewidth', kwargs.get('lw', 1)) with warnings.catch_warnings(): warnings.simplefilter("ignore") trace_data.append(k3d.line(coords, color=c, name=cn_label, width=lw, shader='thick')) else: raise ValueError(f'Unknown display type for connectors "{cn_lay["display"]}"') return trace_data
def __init__( self, lcs, plot: k3d.Plot = None, name: str = None, color: int = RGB_BLACK, show_origin=True, show_trace=True, show_vectors=True, ): """Create a `CoordinateSystemVisualizerK3D`. Parameters ---------- lcs : weldx.transformations.LocalCoordinateSystem Coordinate system that should be visualized plot : k3d.Plot A k3d plotting widget. name : str Name of the coordinate system color : int The RGB color of the coordinate system (affects trace and label) as a 24 bit integer value. show_origin : bool If `True`, the origin of the coordinate system will be highlighted in the color passed as another parameter show_trace : If `True`, the trace of a time dependent coordinate system will be visualized in the color passed as another parameter show_vectors : bool If `True`, the the coordinate axes of the coordinate system are visualized """ coordinates, orientation = self._get_coordinates_and_orientation(lcs) self._lcs = lcs self._color = color self._vectors = k3d.vectors( origins=[coordinates for _ in range(3)], vectors=orientation.transpose(), colors=[[RGB_RED, RGB_RED], [RGB_GREEN, RGB_GREEN], [RGB_BLUE, RGB_BLUE]], labels=[], label_size=1.5, ) self._vectors.visible = show_vectors self._label = None if name is not None: self._label = k3d.text( text=name, position=coordinates + 0.05, color=self._color, size=1, label_box=False, ) self._trace = k3d.line( np.array(lcs.coordinates.values, dtype="float32"), shader="simple", width=0.05, color=color, ) self._trace.visible = show_trace self.origin = platonic.Octahedron(size=0.1).mesh self.origin.color = color self.origin.model_matrix = self._create_model_matrix( coordinates, orientation) self.origin.visible = show_origin if plot is not None: plot += self._vectors plot += self._trace plot += self.origin if self._label is not None: plot += self._label
def foo(): plot = k3d.plot() plot += k3d.line(k3d_line_input, width=0.1) plot.display()
def display_sharpness(mesh=None, plot_meshvert=True, samples=None, samples_distances=None, sharp_vert=None, sharp_curves=None, directions=None, directions_width=0.0025, samples_color=0x0000ff, samples_psize=0.002, mesh_color=0xbbbbbb, meshvert_color=0x666666, meshvert_psize=0.0025, sharpvert_color=0xff0000, sharpvert_psize=0.0025, sharpcurve_color=None, sharpcurve_width=0.0025, as_image=False, plot_height=768, cmap=k3d.colormaps.matplotlib_color_maps.coolwarm_r): plot = k3d.plot(height=plot_height) if None is not mesh: k3d_mesh = k3d.mesh(mesh.vertices, mesh.faces, color=mesh_color) plot += k3d_mesh if plot_meshvert: k3d_points = k3d.points(mesh.vertices, point_size=meshvert_psize, color=meshvert_color) plot += k3d_points k3d_points.shader = 'flat' if None is not samples: colors = None if None is not samples_distances: max_dist = 0.5 colors = k3d.helpers.map_colors(samples_distances, cmap, [0, max_dist]).astype(np.uint32) k3d_points = k3d.points(samples, point_size=samples_psize, colors=colors) else: k3d_points = k3d.points(samples, point_size=samples_psize, color=samples_color) plot += k3d_points k3d_points.shader = 'flat' if None is not directions: vectors = k3d.vectors(samples, directions * samples_distances[..., np.newaxis], use_head=False, line_width=directions_width) print(vectors) plot += vectors if None is not sharp_vert: k3d_points = k3d.points(sharp_vert, point_size=sharpvert_psize, color=sharpvert_color) plot += k3d_points k3d_points.shader = 'flat' if None is not sharp_curves: if None is not sharpcurve_color: color = sharpcurve_color else: import randomcolor rand_color = randomcolor.RandomColor() for i, vert_ind in enumerate(sharp_curves): sharp_points_curve = mesh.vertices[vert_ind] if None is sharpcurve_color: color = rand_color.generate(hue='red')[0] color = int('0x' + color[1:], 16) plt_line = k3d.line(sharp_points_curve, shader='mesh', width=sharpcurve_width, color=color) plot += plt_line plot.grid_visible = False plot.display() if as_image: plot.fetch_screenshot() return Image(data=b64decode(plot.screenshot))
import k3d import numpy as np lines = np.load('vertices.npy') lines_attributes = np.load('attributes.npy') plot = k3d.plot() for l, a in zip(lines, lines_attributes): plot += k3d.line(l, attribute=a, width=0.0001, color_map=k3d.matplotlib_color_maps.Inferno, color_range=[0, 0.5], shader='mesh', compression_level=9) plot.display()
np.array(nn92[['x', 'y', 'z']]), np.resize(np.array(data.loc[92][['x', 'y', 'z']]), (6, 3)) ], axis=1) linestr37 = np.concatenate([ np.array(tr37[['x', 'y', 'z']]), np.resize(np.array(data.loc[37][['x', 'y', 'z']]), (8, 3)) ], axis=1) linestr92 = np.concatenate([ np.array(tr92[['x', 'y', 'z']]), np.resize(np.array(data.loc[92][['x', 'y', 'z']]), (8, 3)) ], axis=1) blue_lines = k3d.line(lines37, shader='mesh', width=0.02) green_lines = k3d.line(lines92, shader='mesh', width=0.02, color=0x00ff00) red_lines = k3d.line(linestr37, shader='mesh', width=0.02, color=0xff0000) magenta_lines = k3d.line(linestr92, shader='mesh', width=0.02, color=0xff00ff) plot3 = k3d.plot() plot3 += system + gbpoints + blue_lines + green_lines + red_lines + magenta_lines ### FOURTH DRAWING np.random.seed(137) gas_data = np.random.uniform(0, 5, size=(5**3, 3)).astype(np.float32) gas = k3d.points(gas_data, point_size=0.15, color=0) bgpoints = k3d.points(gas_data[[13, 17]], point_size=0.15, colors=[0x00ff00, 0x0000ff])
def _process_series(self, series): self._init_cyclers() self._fig.auto_rendering = False # clear data for o in self._fig.objects: self._fig.remove_class(o) for ii, s in enumerate(series): if s.is_3Dline and s.is_point: x, y, z, _ = s.get_data() positions = np.vstack([x, y, z]).T.astype(np.float32) a = dict(point_size=0.2, color=self._convert_to_int(next(self._cl))) line_kw = self._kwargs.get("line_kw", dict()) plt_points = k3d.points(positions=positions, **merge({}, a, line_kw)) plt_points.shader = "mesh" self._fig += plt_points elif s.is_3Dline: x, y, z, param = s.get_data() # K3D doesn't like masked arrays, so filled them with NaN x, y, z = [ np.ma.filled(t) if isinstance(t, np.ma.core.MaskedArray) else t for t in [x, y, z] ] vertices = np.vstack([x, y, z]).T.astype(np.float32) # keyword arguments for the line object a = dict( width=0.1, name=s.label if self._kwargs.get("show_label", False) else None, color=self._convert_to_int(next(self._cl)), shader="mesh", ) if self._use_cm: a["attribute"] = (param.astype(np.float32), ) a["color_map"] = next(self._cm) a["color_range"] = [s.start, s.end] line_kw = self._kwargs.get("line_kw", dict()) line = k3d.line(vertices, **merge({}, a, line_kw)) self._fig += line elif (s.is_3Dsurface and (not s.is_complex)) or (s.is_3Dsurface and s.is_complex and (s.real or s.imag or s.abs)): x, y, z = s.get_data() # K3D doesn't like masked arrays, so filled them with NaN x, y, z = [ np.ma.filled(t) if isinstance(t, np.ma.core.MaskedArray) else t for t in [x, y, z] ] # TODO: # Can I use get_vertices_indices also for non parametric surfaces? if s.is_parametric: vertices, indices = get_vertices_indices(x, y, z) vertices = vertices.astype(np.float32) else: x = x.flatten() y = y.flatten() z = z.flatten() vertices = np.vstack([x, y, z]).T.astype(np.float32) indices = Triangulation(x, y).triangles.astype(np.uint32) self._high_aspect_ratio(x, y, z) a = dict( name=s.label if self._kwargs.get("show_label", False) else None, side="double", flat_shading=False, wireframe=False, color=self._convert_to_int(next(self._cl)), ) if self._use_cm: a["color_map"] = next(self._cm) a["attribute"] = z.astype(np.float32) surface_kw = self._kwargs.get("surface_kw", dict()) surf = k3d.mesh(vertices, indices, **merge({}, a, surface_kw)) self._fig += surf elif s.is_3Dvector and self._kwargs.get("streamlines", False): xx, yy, zz, uu, vv, ww = s.get_data() # K3D doesn't like masked arrays, so filled them with NaN xx, yy, zz, uu, vv, ww = [ np.ma.filled(t) if isinstance(t, np.ma.core.MaskedArray) else t for t in [xx, yy, zz, uu, vv, ww] ] magnitude = np.sqrt(uu**2 + vv**2 + ww**2) min_mag = min(magnitude.flatten()) max_mag = max(magnitude.flatten()) import vtk from vtk.util import numpy_support vector_field = np.array( [uu.flatten(), vv.flatten(), ww.flatten()]).T vtk_vector_field = numpy_support.numpy_to_vtk( num_array=vector_field, deep=True, array_type=vtk.VTK_FLOAT) vtk_vector_field.SetName("vector_field") points = vtk.vtkPoints() points.SetNumberOfPoints(s.n2 * s.n1 * s.n3) for i, (x, y, z) in enumerate( zip(xx.flatten(), yy.flatten(), zz.flatten())): points.SetPoint(i, [x, y, z]) grid = vtk.vtkStructuredGrid() grid.SetDimensions([s.n2, s.n1, s.n3]) grid.SetPoints(points) grid.GetPointData().SetVectors(vtk_vector_field) stream_kw = self._kwargs.get("stream_kw", dict()) starts = stream_kw.pop("starts", None) max_prop = stream_kw.pop("max_prop", 500) streamer = vtk.vtkStreamTracer() streamer.SetInputData(grid) streamer.SetMaximumPropagation(max_prop) if starts is None: seeds_points = get_seeds_points(xx, yy, zz, uu, vv, ww) seeds = vtk.vtkPolyData() points = vtk.vtkPoints() for p in seeds_points: points.InsertNextPoint(p) seeds.SetPoints(points) streamer.SetSourceData(seeds) streamer.SetIntegrationDirectionToForward() elif isinstance(starts, dict): if not all([t in starts.keys() for t in ["x", "y", "z"]]): raise KeyError( "``starts`` must contains the following keys: " + "'x', 'y', 'z', whose values are going to be " + "lists of coordinates.") seeds_points = np.array( [starts["x"], starts["y"], starts["z"]]).T seeds = vtk.vtkPolyData() points = vtk.vtkPoints() for p in seeds_points: points.InsertNextPoint(p) seeds.SetPoints(points) streamer.SetSourceData(seeds) streamer.SetIntegrationDirectionToBoth() else: npoints = stream_kw.get("npoints", 200) radius = stream_kw.get("radius", None) center = 0, 0, 0 if not radius: xmin, xmax = min(xx[0, :, 0]), max(xx[0, :, 0]) ymin, ymax = min(yy[:, 0, 0]), max(yy[:, 0, 0]) zmin, zmax = min(zz[0, 0, :]), max(zz[0, 0, :]) radius = max([ abs(xmax - xmin), abs(ymax - ymin), abs(zmax - zmin) ]) center = (xmax - xmin) / 2, (ymax - ymin) / 2, ( zmax - zmin) / 2 seeds = vtk.vtkPointSource() seeds.SetRadius(radius) seeds.SetCenter(*center) seeds.SetNumberOfPoints(npoints) streamer.SetSourceConnection(seeds.GetOutputPort()) streamer.SetIntegrationDirectionToBoth() streamer.SetComputeVorticity(0) streamer.SetIntegrator(vtk.vtkRungeKutta4()) streamer.Update() streamline = streamer.GetOutput() streamlines_points = numpy_support.vtk_to_numpy( streamline.GetPoints().GetData()) streamlines_velocity = numpy_support.vtk_to_numpy( streamline.GetPointData().GetArray("vector_field")) streamlines_speed = np.linalg.norm(streamlines_velocity, axis=1) vtkLines = streamline.GetLines() vtkLines.InitTraversal() point_list = vtk.vtkIdList() lines = [] lines_attributes = [] while vtkLines.GetNextCell(point_list): start_id = point_list.GetId(0) end_id = point_list.GetId(point_list.GetNumberOfIds() - 1) l = [] v = [] for i in range(start_id, end_id): l.append(streamlines_points[i]) v.append(streamlines_speed[i]) lines.append(np.array(l)) lines_attributes.append(np.array(v)) count = sum([len(l) for l in lines]) vertices = np.nan * np.zeros((count + (len(lines) - 1), 3)) attributes = np.zeros(count + (len(lines) - 1)) c = 0 for k, (l, a) in enumerate(zip(lines, lines_attributes)): vertices[c:c + len(l), :] = l attributes[c:c + len(l)] = a if k < len(lines) - 1: c = c + len(l) + 1 skw = dict(width=0.1, shader="mesh", compression_level=9) if self._use_cm and ("color" not in stream_kw.keys()): skw["color_map"] = next(self._cm) skw["color_range"] = [min_mag, max_mag] skw["attribute"] = attributes else: col = stream_kw.pop("color", next(self._cl)) if not isinstance(col, int): col = self._convert_to_int(col) stream_kw["color"] = col self._fig += k3d.line(vertices.astype(np.float32), **merge({}, skw, stream_kw)) elif s.is_3Dvector: xx, yy, zz, uu, vv, ww = s.get_data() # K3D doesn't like masked arrays, so filled them with NaN xx, yy, zz, uu, vv, ww = [ np.ma.filled(t) if isinstance(t, np.ma.core.MaskedArray) else t for t in [xx, yy, zz, uu, vv, ww] ] xx, yy, zz, uu, vv, ww = [ t.flatten().astype(np.float32) for t in [xx, yy, zz, uu, vv, ww] ] # default values qkw = dict(scale=1) # user provided values quiver_kw = self._kwargs.get("quiver_kw", dict()) qkw = merge(qkw, quiver_kw) scale = qkw["scale"] magnitude = np.sqrt(uu**2 + vv**2 + ww**2) vectors = np.array((uu, vv, ww)).T * scale origins = np.array((xx, yy, zz)).T if self._use_cm and ("color" not in quiver_kw.keys()): colormap = next(self._cm) colors = k3d.helpers.map_colors(magnitude, colormap, []) self._handles[ii] = [qkw, colormap] else: col = quiver_kw.get("color", next(self._cl)) if not isinstance(col, int): col = self._convert_to_int(col) colors = col * np.ones(len(magnitude)) self._handles[ii] = [qkw, None] vec_colors = np.zeros(2 * len(colors)) for i, c in enumerate(colors): vec_colors[2 * i] = c vec_colors[2 * i + 1] = c vec_colors = vec_colors.astype(np.uint32) vec = k3d.vectors( origins=origins - vectors / 2, vectors=vectors, colors=vec_colors, ) self._fig += vec elif s.is_complex and s.is_3Dsurface and ( not s.is_domain_coloring): x, y, mag_arg, colors, colorscale = s.get_data() mag, arg = mag_arg[:, :, 0], mag_arg[:, :, 1] x, y, z = [t.flatten() for t in [x, y, mag]] vertices = np.vstack([x, y, z]).T.astype(np.float32) indices = Triangulation(x, y).triangles.astype(np.uint32) self._high_aspect_ratio(x, y, z) a = dict( name=s.label if self._kwargs.get("show_label", False) else None, side="double", flat_shading=False, wireframe=False, color=self._convert_to_int(next(self._cl)), color_range=[-np.pi, np.pi], ) if self._use_cm: colors = colors.reshape((-1, 3)) a["colors"] = [self._rgb_to_int(c) for c in colors] r = [] loc = np.linspace(0, 1, colorscale.shape[0]) colorscale = colorscale / 255 for l, c in zip(loc, colorscale): r.append(l) r += list(c) a["color_map"] = r a["color_range"] = [-np.pi, np.pi] surface_kw = self._kwargs.get("surface_kw", dict()) surf = k3d.mesh(vertices, indices, **merge({}, a, surface_kw)) self._fig += surf else: raise NotImplementedError( "{} is not supported by {}\n".format( type(s), type(self).__name__) + "K3D-Jupyter only supports 3D plots.") xl = self.xlabel if self.xlabel else "x" yl = self.ylabel if self.ylabel else "y" zl = self.zlabel if self.zlabel else "z" self._fig.axes = [xl, yl, zl] if self.title: self._fig += k3d.text2d(self.title, position=[0.025, 0.015], color=0, size=1, label_box=False) self._fig.auto_rendering = True
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance if isinstance(vp.shape, str) or sum(vp.shape) > 2: colors.printc("Multirendering is not supported in jupyter.", c=1) return #################################################################################### # https://github.com/InsightSoftwareConsortium/itkwidgets # /blob/master/itkwidgets/widget_viewer.py if 'itk' in settings.notebookBackend: from itkwidgets import view settings.notebook_plotter = view(actors=actors2show, cmap='jet', ui_collapsed=True, gradient_opacity=False) #################################################################################### elif settings.notebookBackend == 'k3d': try: import k3d # https://github.com/K3D-tools/K3D-jupyter except: print("Cannot find k3d, install with: pip install k3d") return actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vtk.vtkAssembly): #unpack assemblies acass = ia.unpack() actors2show2 += acass else: actors2show2.append(ia) # vbb, sizes, _, _ = addons.computeVisibleBounds() # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=True, # height=int(vp.size[1]/2), ) # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = 1.2 # set k3d camera settings.notebook_plotter.camera_auto_fit = True if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) if zoom: k3dc[0] /= zoom k3dc[1] /= zoom k3dc[2] /= zoom settings.notebook_plotter.camera = k3dc # else: # vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] # vss = numpy.linalg.norm([vsx, vsy, vsz]) # if zoom: # vss /= zoom # vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target # if viewup == 'z': # vup = (0,0,1) # camera up vector # vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position # elif viewup == 'x': # vup = (1,0,0) # vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position # else: # vup = (0,1,0) # vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position # settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], # vfp[0], vfp[1], vfp[2], # vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False for ia in actors2show2: if isinstance(ia, (vtk.vtkCornerAnnotation, vtk.vtkAssembly)): continue kobj = None kcmap= None name = None if hasattr(ia, 'filename'): if ia.filename: name = os.path.basename(ia.filename) if ia.name: name = os.path.basename(ia.name) #####################################################################scalars # work out scalars first, Points Lines are also Mesh objs if isinstance(ia, (Mesh, shapes.Line, Points)): # print('scalars', ia.name, ia.N()) iap = ia.GetProperty() if isinstance(ia, (shapes.Line, Points)): iapoly = ia.polydata() else: iapoly = ia.clone().clean().triangulate().computeNormals().polydata() vtkscals = None color_attribute = None if ia.mapper().GetScalarVisibility(): vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is None: vtkdata = iapoly.GetCellData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(iapoly) c2p.Update() iapoly = c2p.GetOutput() vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: if not vtkscals.GetName(): vtkscals.SetName('scalars') scals_min, scals_max = ia.mapper().GetScalarRange() color_attribute = (vtkscals.GetName(), scals_min, scals_max) lut = ia.mapper().GetLookupTable() lut.Build() kcmap=[] nlut = lut.GetNumberOfTableValues() for i in range(nlut): r,g,b,a = lut.GetTableValue(i) kcmap += [i/(nlut-1), r,g,b] #####################################################################Volume if isinstance(ia, Volume): # print('Volume', ia.name, ia.dimensions()) kx, ky, kz = ia.dimensions() arr = ia.getPointArray() kimage = arr.reshape(-1, ky, kx) colorTransferFunction = ia.GetProperty().GetRGBTransferFunction() kcmap=[] for i in range(128): r,g,b = colorTransferFunction.GetColor(i/127) kcmap += [i/127, r,g,b] kbounds = numpy.array(ia.imagedata().GetBounds()) \ + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\ * numpy.array([-1,1] * 3) kobj = k3d.volume(kimage.astype(numpy.float32), color_map=kcmap, #color_range=ia.imagedata().GetScalarRange(), alpha_coef=10, bounds=kbounds, name=name, ) settings.notebook_plotter += kobj #####################################################################text elif hasattr(ia, 'info') and 'formula' in ia.info.keys(): pos = (ia.GetPosition()[0],ia.GetPosition()[1]) kobj = k3d.text2d(ia.info['formula'], position=pos) settings.notebook_plotter += kobj #####################################################################Mesh elif isinstance(ia, Mesh) and ia.N() and len(ia.faces()): # print('Mesh', ia.name, ia.N(), len(ia.faces())) kobj = k3d.vtk_poly_data(iapoly, name=name, # color=_rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), wireframe=(iap.GetRepresentation()==1)) if iap.GetInterpolation() == 0: kobj.flat_shading = True settings.notebook_plotter += kobj #####################################################################Points elif isinstance(ia, Points) or ia.NPoints() == ia.NCells(): # print('Points', ia.name, ia.N()) kcols=[] if color_attribute is not None: scals = utils.vtk2numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) kobj = k3d.points(ia.points().astype(numpy.float32), color=_rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader="dot", point_size=3, # point_size=iap.GetPointSize()*sqsize/800, name=name, ) settings.notebook_plotter += kobj #####################################################################Line elif ia.polydata(False).GetNumberOfLines(): # print('Line', ia.name, ia.N(), len(ia.faces()), # ia.polydata(False).GetNumberOfLines(), len(ia.lines()), # color_attribute, [vtkscals]) # kcols=[] # if color_attribute is not None: # scals = utils.vtk2numpy(vtkscals) # kcols = k3d.helpers.map_colors(scals, kcmap, # [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) for i, ln_idx in enumerate(ia.lines()): if i>200: print('WARNING: K3D nr of line segments is limited to 200.') break pts = ia.points()[ln_idx] kobj = k3d.line(pts.astype(numpy.float32), color=_rgb2int(iap.GetColor()), # colors=kcols, opacity=iap.GetOpacity(), shader="thick", # width=iap.GetLineWidth()*sqsize/1000, name=name, ) settings.notebook_plotter += kobj #################################################################################### elif settings.notebookBackend == 'panel' and hasattr(vp, 'window') and vp.window: import panel # https://panel.pyviz.org/reference/panes/VTK.html vp.renderer.ResetCamera() settings.notebook_plotter = panel.pane.VTK(vp.window, width=int(vp.size[0]/1.5), height=int(vp.size[1]/2)) #################################################################################### elif 'ipyvtk' in settings.notebookBackend and hasattr(vp, 'window') and vp.window: from ipyvtklink.viewer import ViewInteractiveWidget vp.renderer.ResetCamera() settings.notebook_plotter = ViewInteractiveWidget(vp.window) #################################################################################### elif '2d' in settings.notebookBackend.lower() and hasattr(vp, 'window') and vp.window: import PIL.Image try: import IPython except ImportError: raise Exception('IPython not available.') from vedo.io import screenshot settings.screeshotLargeImage = True nn = screenshot(returnNumpy=True, scale=settings.screeshotScale+2) pil_img = PIL.Image.fromarray(nn) settings.notebook_plotter = IPython.display.display(pil_img) return settings.notebook_plotter
def skeleton2k3d(neuron, legendgroup, showlegend, label, color, **kwargs): """Convert skeleton (i.e. TreeNeuron) to plotly line plot.""" if neuron.nodes.empty: logger.warning(f'Skipping empty neuron: {neuron.label}') return [] coords = segments_to_coords(neuron, neuron.segments) linewidth = kwargs.get('linewidth', kwargs.get('lw', 1)) # We have to add (None, None, None) to the end of each segment to # make that line discontinuous. For reasons I don't quite understand # we have to also duplicate the first and the last coordinate in each segment # (possibly a bug) coords = np.concatenate([co for seg in coords for co in [seg[:1], seg, seg[-1:], [[None] * 3]]], axis=0) color_kwargs = {} if isinstance(color, np.ndarray) and color.ndim == 2: # Change colors to rgb integers c = [color_to_int(c) for c in color] # Next we have to make colors match the segments in `coords` c = np.asarray(c) ix = dict(zip(neuron.nodes.node_id.values, np.arange(neuron.n_nodes))) # Construct sequence node IDs just like we did in `coords` # (note that we insert a "-1" for breaks between segments) seg_ids = [co for seg in neuron.segments for co in [seg[:1], seg, seg[-1:], [-1]]] seg_ids = np.concatenate(seg_ids, axis=0) # Translate to node indices seg_ix = [ix.get(n, 0) for n in seg_ids] # Now map this to vertex colors seg_colors = [c[i] for i in seg_ix] color_kwargs['colors'] = seg_colors else: color_kwargs['color'] = c = color_to_int(color) with warnings.catch_warnings(): warnings.simplefilter("ignore") trace_data = [k3d.line(coords, width=linewidth, shader='thick', name=label, **color_kwargs)] # Add soma(s): soma = utils.make_iterable(neuron.soma) if kwargs.get('soma', True): # 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: # Skip `None` somas if isinstance(s, type(None)): continue # 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(c, (list, np.ndarray)): s_ix = np.where(neuron.nodes.node_id == s)[0][0] soma_color = int(c[s_ix]) else: soma_color = int(c) 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) with warnings.catch_warnings(): warnings.simplefilter("ignore") trace_data.append(k3d.mesh(vertices=sp.get_vertices() + n[['x', 'y', 'z']].values.astype('float32'), indices=sp.get_faces().astype('uint32'), color=soma_color, flat_shading=False, name=f"soma of {label}" )) return trace_data