def _init_figure(self, x, y, z, triangles, figsize, figlims): """ Initialize the figure by plotting the surface without any overlay. x: x coordinates of vertices (V x 1 numpy array) y: y coordinates of vertices (V x 1 numpy array) z: z coordinates of vertices (V x 1 numpy array) triangles: triangle specifications (T x 3 numpy array, where T=#triangles) figsize: 2x1 list of integers figlims: 3x2 list of integers """ self.fig = p3.figure(width=figsize[0], height=figsize[1]) self.fig.camera_fov = 1 self.fig.style = { "axes": { "color": "black", "label": {"color": "black"}, "ticklabel": {"color": "black"}, "visible": False, }, "background-color": "white", "box": {"visible": False}, } self.fig.xlim = (figlims[0][0], figlims[0][1]) self.fig.ylim = (figlims[1][0], figlims[1][1]) self.fig.zlim = (figlims[2][0], figlims[2][1]) # draw the tetrahedron p3.plot_trisurf( x, y, z, triangles=triangles, color=np.ones((len(x), 3)) )
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r'): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation l_vert_mean, r_vert_mean = self.compute_surface_map(radius, freq_range) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_vert_mean)), np.nanmax(np.abs(r_vert_mean))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_vert_mean) l_colors = np.full((l_vert_mean.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_vert_mean[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_vert_mean) r_colors = np.full((r_vert_mean.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_vert_mean[valid_r_inds]) # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def plot(self, plot_mesh=True, plot_voxels=True, width=800, height=600, voxel_count_offset=0, voxel_limit=None, use_centroids_instead=False, scaling=1, mesh_color='red', **kwargs): """ This method needs better documentation. :param **kwargs: Is used in ipyvolume.pylab.scatter() or ipyvolume.pylab.plot() depending on whether use_centroids_instead is set to true or not. """ if plot_mesh: if self.triangles is None: raise ValueError( "There is no triangle data stored for this mesh!") else: fig = p3.figure(width=width, height=height) p3.plot_trisurf(*self.vertices.T * scaling, self.triangles, color=mesh_color) if plot_voxels: self.voxels.plot( width=width, height=height, voxel_count_offset=voxel_count_offset, voxel_limit=voxel_limit, use_centroids_instead=use_centroids_instead, ipyvol_fig=fig, scaling=scaling, **kwargs) else: p3.squarelim() p3.show() elif plot_voxels: try: fig = p3.figure(width=width, height=height) self.voxels.plot(width=width, height=height, voxel_count_offset=voxel_count_offset, voxel_limit=voxel_limit, use_centroids_instead=use_centroids_instead, ipyvol_fig=fig, scaling=scaling, **kwargs) except AttributeError: raise AttributeError( "This object does not have a Voxels object, you must initialize the voxel mesh with a Voxels object or run voxelize() to generate new voxels." )
def _create_mesh(points, color="black", solid=False, lines=True, triangle_indices=None, line_indices=None): """ create an ipyvolume mesh from a number of points Parameters ---------- points: list [[x, y, z], ...] color: str solid: bool triangle_indices: list or None [[i, j, k], ...], if None then computed from scipy.spatial.qhull.ConvexHull triangles line_indices: list or None [[i, j], ...], if None then computed from scipy.spatial.qhull.ConvexHull triangles Returns ------- """ x, y, z = np.array(points).T try: hull = ConvexHull(points) except: hull = ConvexHull(points, qhull_options='QJ') if triangle_indices is None: triangle_indices = hull.simplices.tolist() if line_indices is None: line_indices = [] for i, j, k in hull.simplices.tolist(): line_indices += [[i, j], [i, k], [j, k]] mesh = p3.plot_trisurf(x, y, z, triangles=triangle_indices, lines=line_indices, color=color) if not solid: mesh.visible_faces = False if not lines: mesh.visible_lines = False return mesh
def showSurface(surface,overlay=None,frame=0,newfigure=True,colormap='summer',figsize=np.array([300,400]), figlims=np.array([[-75,75],[-75,75],[-75,75]])): ''' Displays a surface mesh in gifti or FreeSurfer (FS) surface format with/without an overlay inside Jupyter notebook for interactive visualization. Parameters ---------- surface: str, gifti opject Path to surface file in gifti or FS surface format or an already loaded gifti object of surface overlay: str, gifti opject Path to overlay file in gifti or FS annot or anaotimcal (.curv,.sulc,.thickness) format or an already loaded gifti object of overlay, default None frame: int indice of the frame (timepoint or functional data frame) to show newfigure: bool Create a new figure else prints into the last figure (in order to visualize both hemispheres in one plot), default True colormap: string A matplotlib colormap, default summer figsize: ndarray Size of the figure to display, default [600,600] figLims: ndarray x,y and z limits of the axes, default [[-100,100],[-100,100],[-100,100]]) ''' if isinstance(surface,str): if not os.path.exists(surface): error('File does not exist, please provide a valid file path to a gifti or FreeSurfer file.') filename, file_extension = os.path.splitext(surface) if file_extension is '.gii': surface = nb.load(surface) else: fsgeometry = nb.freesurfer.read_geometry(surface) x,y,z = fsgeometry[0].T vertex_edges=fsgeometry[1] if isinstance(surface,nb.gifti.gifti.GiftiImage): try: vertex_spatial=surface.darrays[0] vertex_edges=surface.darrays[1] x, y, z = vertex_spatial.data.T except: raise ValueError('Please provide a valid gifti file.') if not isinstance(frame,int): ValueError('Please provide a valid integer frame index.') if isinstance(overlay,list): if frame>len(overlay) or frame < 0: error('Frame index out of bounds, please provide a valid frame index.') overlay = overlay[frame] if isinstance(overlay,str): if not os.path.exists(overlay): error('File does not exist, please provide a valid file path to a gifti or FreeSurfer file.') filename, file_extension = os.path.splitext(overlay) if file_extension is '.gii': overlay = nb.load(overlay) elif (file_extension in ('.annot','')): annot = nb.freesurfer.read_annot(overlay) activation = annot[0] elif (file_extension in ('.curv','.thickness','.sulc')): activation = nb.freesurfer.read_morph_data(overlay) if isinstance(overlay,nb.gifti.gifti.GiftiImage): try: activation=overlay.darrays[0].data except: raise ValueError('Please provide a valid gifti file') if newfigure: fig = p3.figure(width=figsize[0], height=figsize[1]) fig.camera_fov = 1 fig.style = {'axes': {'color': 'black', 'label': {'color': 'black'}, 'ticklabel': {'color': 'black'}, 'visible': False}, 'background-color': 'white', 'box': {'visible': False}} fig.xlim = (figlims[0][0], figlims[0][1]) fig.ylim = (figlims[1][0], figlims[1][1]) fig.zlim = (figlims[2][0], figlims[2][1]) # plot surface if overlay is None: p3.plot_trisurf(x, y, z, triangles=vertex_edges.data) else: my_color = plt.cm.get_cmap(colormap) colors=my_color((activation-min(activation))/(max(activation)-min(activation))) p3.plot_trisurf(x, y, z, triangles=vertex_edges.data, color=colors[:,:3]) if newfigure: p3.show()
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r', n_perms=100, min_n=5, res_key='t-stat'): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use n_perms: int Number of permutations to do when computing our t-statistic significance thresholds min_n: int Vertices with less than this number of subjects will be plotted in gray, regardless of the significance val res_key: str Column name of dataframe to use as the metric Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation. First get vertex x subject arrays l_vert_vals, r_vert_vals = self.compute_surface_map(radius, freq_range, res_key) # we will actually be plotting t-statistics, so compute those l_ts, l_ps = ttest_1samp(l_vert_vals, 0, axis=1, nan_policy='omit') r_ts, r_ps = ttest_1samp(r_vert_vals, 0, axis=1, nan_policy='omit') # not let's compute our significance thresholds via non-parametric permutation procedure sig_thresh = self.compute_permute_dist_par(l_vert_vals, r_vert_vals, n_perms=n_perms) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_ts)), np.nanmax(np.abs(r_ts))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_ts) & (np.sum(np.isnan(l_vert_vals), axis=1) >= min_n) l_colors = np.full((l_ts.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_ts[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_ts) & (np.sum(np.isnan(r_vert_vals), axis=1) >= min_n) r_colors = np.full((r_ts.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_ts[valid_r_inds]) # lastly, mask out vertices that do not meet our significance thresh sig_l = (l_ts < sig_thresh[0]) | (l_ts > sig_thresh[1]) sig_r = (r_ts < sig_thresh[0]) | (r_ts > sig_thresh[1]) l_colors[~sig_l] = [.7, .7, .7, 0.] r_colors[~sig_r] = [.7, .7, .7, 0.] # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r', n_perms=100, min_n=5): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use n_perms: int Number of permutations to do when computing our t-statistic significance thresholds min_n: int Vertices with less than this number of subjects will be plotted in gray, regardless of the significance val Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation. First get vertex x subject arrays l_vert_vals, r_vert_vals = self.compute_surface_map(radius, freq_range) # we will actually be plotting t-statistics, so compute those l_ts, l_ps = ttest_1samp(l_vert_vals, 0, axis=1, nan_policy='omit') r_ts, r_ps = ttest_1samp(r_vert_vals, 0, axis=1, nan_policy='omit') # not let's compute our significance thresholds via non-parametric permutation procedure sig_thresh = self.compute_permute_dist_par(l_vert_vals, r_vert_vals, n_perms=n_perms) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_ts)), np.nanmax(np.abs(r_ts))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_ts) & (np.sum(np.isnan(l_vert_vals), axis=1) >= min_n) l_colors = np.full((l_ts.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_ts[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_ts) & (np.sum(np.isnan(r_vert_vals), axis=1) >= min_n) r_colors = np.full((r_ts.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_ts[valid_r_inds]) # lastly, mask out vertices that do not meet our significance thresh sig_l = (l_ts < sig_thresh[0]) | (l_ts > sig_thresh[1]) sig_r = (r_ts < sig_thresh[0]) | (r_ts > sig_thresh[1]) l_colors[~sig_l] = [.7, .7, .7, 0.] r_colors[~sig_r] = [.7, .7, .7, 0.] # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def fermi3D(procar, outcar, bands=-1, scale=1, mode="plain", st=False, **kwargs): """ This function plots 3d fermi surface list of acceptable kwargs : plotting_package nprocess face_colors arrow_colors arrow_spin atom orbital spin """ welcome() # Initilizing the arguments : if "plotting_package" in kwargs: plotting_package = kwargs["plotting_package"] else: plotting_package = "mayavi" if "nprocess" in kwargs: nprocess = kwargs["nprocess"] else: nprocess = 2 if "face_colors" in kwargs: face_colors = kwargs["face_colors"] else: face_colors = None if "cmap" in kwargs: cmap = kwargs["cmap"] else: cmap = "jet" if "atoms" in kwargs: atoms = kwargs["atoms"] else: atoms = [-1] # project all atoms if "orbitals" in kwargs: orbitals = kwargs["orbitals"] else: orbitals = [-1] if "spin" in kwargs: spin = kwargs["spin"] else: spin = [0] if "mask_points" in kwargs: mask_points = kwargs["mask_points"] else: mask_points = 1 if "energy" in kwargs: energy = kwargs["energy"] else: energy = 0 if "transparent" in kwargs: transparent = kwargs["transparent"] else: transparent = False if "arrow_projection" in kwargs: arrow_projection = kwargs["arrow_projection"] else: arrow_projection = 2 if plotting_package == "mayavi": try: from mayavi import mlab from tvtk.api import tvtk except: print( "You have selected mayavi as plottin package. please install mayavi or choose a different package" ) return elif plotting_package == "plotly": try: import plotly.plotly as py import plotly.figure_factory as ff import plotly.graph_objs as go cmap = mpl.cm.get_cmap(cmap) figs = [] except: print( "You have selected plotly as plottin package. please install plotly or choose a different package" ) return elif plotting_package == "matplotlib": try: import matplotlib.pylab as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection except: print( "You have selected matplotlib as plotting package. please install matplotlib or choose a different package" ) return elif plotting_package == "ipyvolume": try: import ipyvolume.pylab as ipv except: print( "You have selected ipyvolume as plotting package. please install ipyvolume or choose a different package" ) return permissive = False # get fermi from outcar outcarparser = UtilsProcar() e_fermi = outcarparser.FermiOutcar(outcar) print("Fermi=", e_fermi) e_fermi += energy # get reciprocal lattice from outcar recLat = outcarparser.RecLatOutcar(outcar) # parsing the Procar file procarFile = ProcarParser() procarFile.readFile(procar, permissive) poly = get_wigner_seitz(recLat) # plot brilliouin zone if plotting_package == "mayavi": brillouin_point = [] brillouin_faces = [] point_count = 0 for iface in poly: single_face = [] for ipoint in iface: single_face.append(point_count) brillouin_point.append(list(ipoint)) point_count += 1 brillouin_faces.append(single_face) polydata_br = tvtk.PolyData(points=brillouin_point, polys=brillouin_faces) mlab.pipeline.surface( polydata_br, representation="wireframe", color=(0, 0, 0), line_width=4, name="BRZ", ) elif plotting_package == "plotly": for iface in poly: iface = np.pad(iface, ((0, 1), (0, 0)), "wrap") x, y, z = iface[:, 0], iface[:, 1], iface[:, 2] plane = go.Scatter3d(x=x, y=y, z=z, mode="lines", line=dict(color="black", width=4)) figs.append(plane) elif plotting_package == "matplotlib": fig = plt.figure() ax = fig.add_subplot(111, projection="3d") brillouin_zone = Poly3DCollection(poly, facecolors=["None"] * len(poly), alpha=1, linewidth=4) brillouin_zone.set_edgecolor("k") ax.add_collection3d(brillouin_zone, zs=0, zdir="z") br_points = [] for iface in poly: for ipoint in iface: br_points.append(ipoint) br_points = np.unique(br_points, axis=0) print("Number of bands: %d" % procarFile.bandsCount) print("Number of koints %d" % procarFile.kpointsCount) print("Number of ions: %d" % procarFile.ionsCount) print("Number of orbitals: %d" % procarFile.orbitalCount) print("Number of spins: %d" % procarFile.ispin) # selecting the data data = ProcarSelect(procarFile, deepCopy=True) if bands == -1: bands = range(data.bands.shape[1]) kvector = data.kpoints kmax = np.max(kvector) kmin = np.min(kvector) if abs(kmax) != abs(kmin): print("The mesh provided is gamma center, symmetrizing data") print("For a better fermi surface, use a non-gamma centered k-mesh") data = symmetrize(data) kvector = data.kpoints kvector_red = data.kpoints.copy() kvector_cart = np.dot(kvector_red, recLat) # This section finds points that are outside of the 1st BZ and and creates those points in the 1st BZ kvector_cart, kvector_red, has_points_out = bring_pnts_to_BZ( recLat, kvector_cart, kvector_red, br_points) # has_points_out = False # getting the mesh grid in each dirrection kx_red = np.unique(kvector_red[:, 0]) ky_red = np.unique(kvector_red[:, 1]) kz_red = np.unique(kvector_red[:, 2]) # getting the lengths between kpoints in each direction klength_x = np.abs(kx_red[-1] - kx_red[-2]) klength_y = np.abs(ky_red[-1] - ky_red[-2]) klength_z = np.abs(kz_red[-1] - kz_red[-2]) klengths = [klength_x, klength_y, klength_z] # getting number of kpoints in each direction with the addition of kpoints needed to sample the 1st BZ fully (in reduced) nkx_red = kx_red.shape[0] nky_red = ky_red.shape[0] nkz_red = kz_red.shape[0] # getting numner of kpoints in each direction provided by vasp nkx_orig = np.unique(kvector[:, 0]).shape[0] nky_orig = np.unique(kvector[:, 1]).shape[0] nkz_orig = np.unique(kvector[:, 2]).shape[0] # Amount of kpoints needed to add on to fully sample 1st BZ padding_x = (nkx_red - nkx_orig) // 2 padding_y = (nky_red - nky_orig) // 2 padding_z = (nkz_red - nkz_orig) // 2 if mode == "parametric": data.selectIspin(spin) data.selectAtoms(atoms, fortran=False) data.selectOrbital(orbitals) elif mode == "external": if "color_file" in kwargs: rf = open(kwargs["color_file"]) lines = rf.readlines() counter = 0 color_kvector = [] color_eigen = [] for iline in lines: if counter < 2: if "band" in iline: counter += 1 continue temp = [float(x) for x in iline.split()] color_kvector.append([temp[0], temp[1], temp[2]]) counter = -1 for iline in lines: if "band" in iline: counter += 1 iband = int(iline.split()[-1]) color_eigen.append([]) continue color_eigen[counter].append(float(iline.split()[-1])) rf.close() color_kvector = np.array(color_kvector) color_kvector_red = color_kvector.copy() color_kvector_cart = np.dot(color_kvector, recLat) if has_points_out: color_kvector_cart, color_kvector_red, temp = bring_pnts_to_BZ( recLat, color_kvector_cart, color_kvector_red, br_points) else: print( "mode selected was external, but no color_file name was provided" ) return if st: dataX = ProcarSelect(procarFile, deepCopy=True) dataY = ProcarSelect(procarFile, deepCopy=True) dataZ = ProcarSelect(procarFile, deepCopy=True) dataX.kpoints = data.kpoints dataY.kpoints = data.kpoints dataZ.kpoints = data.kpoints dataX.spd = data.spd dataY.spd = data.spd dataZ.spd = data.spd dataX.bands = data.bands dataY.bands = data.bands dataZ.bands = data.bands dataX.selectIspin([1]) dataY.selectIspin([2]) dataZ.selectIspin([3]) dataX.selectAtoms(atoms, fortran=False) dataY.selectAtoms(atoms, fortran=False) dataZ.selectAtoms(atoms, fortran=False) dataX.selectOrbital(orbitals) dataY.selectOrbital(orbitals) dataZ.selectOrbital(orbitals) ic = 0 for iband in bands: print("Plotting band %d" % iband) eigen = data.bands[:, iband] # mapping the eigen values on the mesh grid to a matrix mapped_func, kpoint_matrix = mapping_func(kvector, eigen) # adding the points from the 2nd BZ to 1st BZ to fully sample the BZ. Check np.pad("wrap") for more information mapped_func = np.pad( mapped_func, ((padding_x, padding_x), (padding_y, padding_y), (padding_z, padding_z)), "wrap", ) # Fourier interpolate the mapped function E(x,y,z) surf_equation = fft_interpolate(mapped_func, scale) # after the FFT we loose the center of the BZ, using numpy roll we bring back the center of the BZ surf_equation = np.roll(surf_equation, (scale) // 2, axis=[0, 1, 2]) try: # creating the isosurface if possible verts, faces, normals, values = measure.marching_cubes_lewiner( surf_equation, e_fermi) except: print("No isosurface for this band") continue # the vertices provided are scaled and shifted to start from zero # we center them to zero, and rescale them to fit the real BZ by multiplying by the klength in each direction for ix in range(3): verts[:, ix] -= verts[:, ix].min() verts[:, ix] -= (verts[:, ix].max() - verts[:, ix].min()) / 2 verts[:, ix] *= klengths[ix] / scale # the vertices need to be transformed to reciprocal spcae from recuded space, to find the points that are # in 2nd BZ, to be removed verts = np.dot(verts, recLat) # identifying the points in 2nd BZ and removing them if has_points_out: args = [] for ivert in range(len(verts)): args.append([br_points, verts[ivert]]) p = Pool(nprocess) results = np.array(p.map(is_outside, args)) p.close() out_verts = np.arange(0, len(results))[results] new_faces = [] # outs_bool_mat = np.zeros(shape=faces.shape,dtype=np.bool) for iface in faces: remove = False for ivert in iface: if ivert in out_verts: remove = True continue if not remove: new_faces.append(iface) faces = np.array(new_faces) print("done removing") # At this point we have the plain Fermi surface, we can color the surface depending on the projection # We create the center of faces by averaging coordinates of corners if mode == "parametric": character = data.spd[:, iband] centers = np.zeros(shape=(len(faces), 3)) for iface in range(len(faces)): centers[iface, 0:3] = np.average(verts[faces[iface]], axis=0) colors = interpolate.griddata(kvector_cart, character, centers, method="nearest") elif mode == "external": character = np.array(color_eigen[ic]) ic += 1 centers = np.zeros(shape=(len(faces), 3)) for iface in range(len(faces)): centers[iface, 0:3] = np.average(verts[faces[iface]], axis=0) colors = interpolate.griddata(color_kvector_cart, character, centers, method="nearest") if st: projection_x = dataX.spd[:, iband] projection_y = dataY.spd[:, iband] projection_z = dataZ.spd[:, iband] verts_spin, faces_spin, normals, values = measure.marching_cubes_lewiner( mapped_func, e_fermi) for ix in range(3): verts_spin[:, ix] -= verts_spin[:, ix].min() verts_spin[:, ix] -= (verts_spin[:, ix].max() - verts_spin[:, ix].min()) / 2 verts_spin[:, ix] *= klengths[ix] verts_spin = np.dot(verts_spin, recLat) if has_points_out: args = [] for ivert in range(len(verts_spin)): args.append([br_points, verts_spin[ivert]]) p = Pool(nprocess) results = np.array(p.map(is_outside, args)) p.close() out_verts = np.arange(0, len(results))[results] new_faces = [] for iface in faces_spin: remove = False for ivert in iface: if ivert in out_verts: remove = True continue if not remove: new_faces.append(iface) faces_spin = np.array(new_faces) centers = np.zeros(shape=(len(faces_spin), 3)) for iface in range(len(faces_spin)): centers[iface, 0:3] = np.average(verts_spin[faces_spin[iface]], axis=0) colors1 = interpolate.griddata(kvector_cart, projection_x, centers, method="linear") colors2 = interpolate.griddata(kvector_cart, projection_y, centers, method="linear") colors3 = interpolate.griddata(kvector_cart, projection_z, centers, method="linear") spin_arrows = np.vstack((colors1, colors2, colors3)).T if plotting_package == "mayavi": polydata = tvtk.PolyData(points=verts, polys=faces) if face_colors != None: mlab.pipeline.surface( polydata, representation="surface", color=face_colors[ic], opacity=1, name="band-" + str(iband), ) ic += 1 else: if mode == "plain": if not (transparent): s = mlab.pipeline.surface( polydata, representation="surface", color=(0, 0.5, 1), opacity=1, name="band-" + str(iband), ) elif mode == "parametric" or mode == "external": polydata.cell_data.scalars = colors polydata.cell_data.scalars.name = "celldata" mlab.pipeline.surface(polydata, vmin=0, vmax=colors.max(), colormap=cmap) cb = mlab.colorbar(orientation="vertical") if st: x, y, z = list(zip(*centers)) u, v, w = list(zip(*spin_arrows)) pnts = mlab.quiver3d( x, y, z, u, v, w, line_width=5, mode="arrow", resolution=25, reset_zoom=False, name="spin-" + str(iband), mask_points=mask_points, scalars=spin_arrows[:, arrow_projection], vmin=-1, vmax=1, colormap=cmap, ) pnts.glyph.color_mode = "color_by_scalar" pnts.glyph.glyph_source.glyph_source.shaft_radius = 0.05 pnts.glyph.glyph_source.glyph_source.tip_radius = 0.1 elif plotting_package == "plotly": if mode == "plain": if not (transparent): x, y, z = zip(*verts) fig = ff.create_trisurf( x=x, y=y, z=z, plot_edges=False, simplices=faces, title="band-%d" % ic, ) figs.append(fig["data"][0]) elif mode == "parametric" or mode == "external": face_colors = cmap(colors) colormap = [ "rgb(%i,%i,%i)" % (x[0], x[1], x[2]) for x in (face_colors * 255).round() ] x, y, z = zip(*verts) fig = ff.create_trisurf( x=x, y=y, z=z, plot_edges=False, colormap=colormap, simplices=faces, show_colorbar=True, title="band-%d" % ic, ) figs.append(fig["data"][0]) elif plotting_package == "matplotlib": if mode == "plain": x, y, z = zip(*verts) ax.plot_trisurf(x, y, faces, z, linewidth=0.2, antialiased=True) elif mode == "parametric" or mode == "external": print( "coloring the faces is not implemented in matplot lib, please use another plotting package.we recomend mayavi." ) elif plotting_package == "ipyvolume": if mode == "plain": ipv.figure() ipv.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces) elif mode == "paramteric" or mode == "external": face_colors = cmap(colors) colormap = [ "rgb(%i,%i,%i)" % (x[0], x[1], x[2]) for x in (face_colors * 255).round() ] ipv.figure() ipv.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces, color=cmap) if plotting_package == "mayavi": mlab.colorbar(orientation="vertical") # ,label_fmt='%.1f') mlab.show() elif plotting_package == "plotly": layout = go.Layout(showlegend=False) fig = go.Figure(data=figs, layout=layout) py.iplot(fig) elif plotting_package == "matplotlib": plt.show() elif plotting_package == "ipyvolume": ipv.show() return