def getAxisToPlotter(p, axis=0, size=10): axis3D = np.eye(3)[axis] * 1.0 arrow = pv.Arrow(start=size * axis3D, direction=axis3D, tip_length=0.5, tip_radius=0.3, shaft_radius=.05) axis1 = pv.Cylinder(radius=0.05, direction=axis3D, center=0.5 * size * axis3D, height=10.0, resolution=100) p.add_mesh(arrow, color='orange') p.add_mesh(axis1, color='orange') if axis in [0, 2]: arrow = pv.Arrow(start=size * axis3D * -1, direction=axis3D * -1, tip_length=0.5, tip_radius=0.3, shaft_radius=.05) axis1 = pv.Cylinder(radius=0.05, direction=axis3D, center=0.5 * size * axis3D * -1, height=10.0, resolution=100) p.add_mesh(axis1, color='orange') p.add_mesh(arrow, color='orange') return
def plotAxis(p, axis=0, size=10, biDirectional=False, label='', labelShift=(0, 0, 0), axisColor='orange', axisShift=(0, 0, 0), labelFontSize=40, reverse=False): axis3D = np.eye(3)[axis] * 1.0 if reverse: axis3D *= -1 axisShift = np.array(axisShift) arrow = pv.Arrow(start=size * axis3D + axisShift, direction=axis3D, tip_length=0.5, tip_radius=0.3, shaft_radius=.05) axis1 = pv.Cylinder(radius=0.05, direction=axis3D, center=0.5 * size * axis3D + axisShift, height=size, resolution=100) p.add_mesh(arrow, color=axisColor) p.add_mesh(axis1, color=axisColor) if biDirectional: arrow = pv.Arrow(start=size * axis3D * (-1) + axisShift, direction=axis3D * -1, tip_length=0.5, tip_radius=0.3, shaft_radius=.05) axis1 = pv.Cylinder(radius=0.05, direction=axis3D, center=0.5 * size * axis3D * (-1) + axisShift, height=size, resolution=100) p.add_mesh(axis1, color=axisColor) p.add_mesh(arrow, color=axisColor) if label != '': labelPos = axis3D * size + np.array(labelShift) + axisShift p.add_point_labels([labelPos], [label], font_family='times', font_size=labelFontSize, fill_shape=False, shape=None, bold=False, text_color=axisColor, show_points=False, point_size=0, point_color=(0.3, 0.3, 0.3)) return
def test_subplot_groups(): plotter = pyvista.Plotter(shape=(3, 3), groups=[(1, [1, 2]), (np.s_[:], 0)]) plotter.subplot(0, 0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(0, 1) plotter.add_mesh(pyvista.Cube()) plotter.subplot(0, 2) plotter.add_mesh(pyvista.Arrow()) plotter.subplot(1, 1) plotter.add_mesh(pyvista.Cylinder()) plotter.subplot(2, 1) plotter.add_mesh(pyvista.Cone()) plotter.subplot(2, 2) plotter.add_mesh(pyvista.Box()) # Test group overlap with pytest.raises(AssertionError): # Partial overlap pyvista.Plotter(shape=(3, 3), groups=[([1, 2], [0, 1]), ([0, 1], [1, 2])]) with pytest.raises(AssertionError): # Full overlap (inner) pyvista.Plotter(shape=(4, 4), groups=[(np.s_[:], np.s_[:]), ([1, 2], [1, 2])]) with pytest.raises(AssertionError): # Full overlap (outer) pyvista.Plotter(shape=(4, 4), groups=[(1, [1, 2]), ([0, 3], np.s_[:])])
def get_drawing_arrow( start: Sequence[float] | None = None, direction: Sequence[float] | None = None, length: float = 1, shaft_radius: float = 0.05, shaft_resolution: int = 20, tip_length: float = 0.25, tip_radius: float = 0.1, tip_resolution: int = 20, ) -> "pv.MultiBlock": """Creates PyVista 3D arrow from cone and cylider. Args: start: Starting point (Å) direction: Direction vector (Å) length: Length (Å) shaft_radius: Shaft radius (Å) shaft_resolution: Shaft resolution tip_length: Tip length (Å) tip_radius:: Tip radius (Å) tip_resolution: Tip resoluation Returns: arrow: 3D arrow """ # Set start and direction if start is None: start = [0, 0, 0] if direction is None: direction = [1, 0, 0] start: Array1DFloat = np.array(start) direction = np.array(direction) / np.linalg.norm(direction) # Create cylinder cylinder_length = length - tip_length cylinder_center = start + length * direction / 2 cyl = pv.Cylinder( center=cylinder_center, direction=direction, radius=shaft_radius, height=cylinder_length, resolution=shaft_resolution, ) # Create cone cone_center = start + (cylinder_length + tip_length / 2) * direction cone = get_drawing_cone( center=cone_center, direction=direction, radius=tip_radius, height=tip_length, resolution=tip_resolution, ) # Assemble to arrow arrow = pv.MultiBlock() arrow.append(cyl) arrow.append(cone) return arrow
def get_img(): """Generate a screenshot of a simple pyvista mesh. Returns ------- str Local path within the static directory of the image. """ # get the user selected mesh option meshtype = request.args.get('meshtype') if meshtype == 'Sphere': mesh = pyvista.Sphere() elif meshtype == 'Cube': mesh = pyvista.Cube() elif meshtype == 'Bohemian Dome': mesh = pyvista.ParametricBohemianDome() elif meshtype == 'Cylinder': mesh = pyvista.Cylinder() else: # invalid entry raise ValueError('Invalid Option') # generate screenshot filename = f'{meshtype}.png' filepath = os.path.join(static_image_path, filename) mesh.plot(off_screen=True, window_size=(300, 300), screenshot=filepath) return os.path.join('images', filename)
def _create_testing_scene(empty_scene, show=False, off_screen=False): if empty_scene: plotter = pyvista.BackgroundPlotter(show=show, off_screen=off_screen) else: plotter = pyvista.BackgroundPlotter(shape=(2, 2), border=True, border_width=10, border_color='grey', show=show, off_screen=off_screen) plotter.set_background('black', top='blue') plotter.subplot(0, 0) cone = pyvista.Cone(resolution=4) actor = plotter.add_mesh(cone) plotter.remove_actor(actor) plotter.add_text('Actor is removed') plotter.subplot(0, 1) plotter.add_mesh(pyvista.Box(), color='green', opacity=0.8) plotter.subplot(1, 0) cylinder = pyvista.Cylinder(resolution=6) plotter.add_mesh(cylinder, smooth_shading=True) plotter.show_bounds() plotter.subplot(1, 1) sphere = pyvista.Sphere(phi_resolution=6, theta_resolution=6) plotter.add_mesh(sphere) plotter.enable_cell_picking() return plotter
def test_cylinder(): cylinder = pv.Cylinder().tri_filter() # cylinder.clean(inplace=True) clus = pyacvd.Clustering(cylinder) clus.subdivide(3) nclus = 500 clus.cluster(nclus) remesh = clus.create_mesh() assert remesh.n_points == nclus
def test_multi_renderers_subplot_ind_1x3(): # Test subplot 3 on bottom, 1 on top plotter = pyvista.Plotter(shape='1|3') # First column plotter.subplot(0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(1) plotter.add_mesh(pyvista.Cube()) plotter.subplot(2) plotter.add_mesh(pyvista.Cylinder()) plotter.subplot(3) plotter.add_mesh(pyvista.Cone()) plotter.show(before_close_callback=verify_cache_image)
def test_subplot_groups(): plotter = pyvista.Plotter(shape=(3,3), groups=[(1,[1,2]),(np.s_[:],0)]) plotter.subplot(0, 0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(0, 1) plotter.add_mesh(pyvista.Cube()) plotter.subplot(0, 2) plotter.add_mesh(pyvista.Arrow()) plotter.subplot(1, 1) plotter.add_mesh(pyvista.Cylinder()) plotter.subplot(2, 1) plotter.add_mesh(pyvista.Cone()) plotter.subplot(2, 2) plotter.add_mesh(pyvista.Box()) plotter.show(before_close_callback=verify_cache_image)
import pyvista as pv from pyvista import examples import numpy as np from matplotlib.cm import get_cmap ############################################################################### # Texture mapping is easily implemented using PyVista. Many of the geometric # objects come preloaded with texture coordinates, so quickly creating a # surface and displaying an image is simply: # load a sample texture tex = examples.download_masonry_texture() # create a surface to host this texture surf = pv.Cylinder() surf.plot(texture=tex) ############################################################################### # But what if your dataset doesn't have texture coordinates? Then you can # harness the :func:`pyvista.DataSetFilters.texture_map_to_plane` filter to # properly map an image to a dataset's surface. # For example, let's map that same image of bricks to a curvey surface: # create a structured surface x = np.arange(-10, 10, 0.25) y = np.arange(-10, 10, 0.25) x, y = np.meshgrid(x, y) r = np.sqrt(x ** 2 + y ** 2)
def test_multi_renderers(): plotter = pyvista.Plotter(shape=(2, 2), off_screen=OFF_SCREEN) plotter.subplot(0, 0) plotter.add_text('Render Window 0', font_size=30) sphere = pyvista.Sphere() plotter.add_mesh(sphere, scalars=sphere.points[:, 2]) plotter.add_scalar_bar('Z', vertical=True) plotter.subplot(0, 1) plotter.add_text('Render Window 1', font_size=30) plotter.add_mesh(pyvista.Cube(), show_edges=True) plotter.subplot(1, 0) plotter.add_text('Render Window 2', font_size=30) plotter.add_mesh(pyvista.Arrow(), color='y', show_edges=True) plotter.subplot(1, 1) plotter.add_text('Render Window 3', position=(0., 0.), font_size=30, viewport=True) plotter.add_mesh(pyvista.Cone(), color='g', show_edges=True, culling=True) plotter.add_bounding_box(render_lines_as_tubes=True, line_width=5) plotter.show_bounds(all_edges=True) plotter.update_bounds_axes() plotter.show() # Test subplot indices (2 rows by 1 column) plotter = pyvista.Plotter(shape=(2, 1), off_screen=OFF_SCREEN) # First row plotter.subplot(0, 0) plotter.add_mesh(pyvista.Sphere()) # Second row plotter.subplot(1, 0) plotter.add_mesh(pyvista.Cube()) plotter.show() # Test subplot indices (1 row by 2 columns) plotter = pyvista.Plotter(shape=(1, 2), off_screen=OFF_SCREEN) # First column plotter.subplot(0, 0) plotter.add_mesh(pyvista.Sphere()) # Second column plotter.subplot(0, 1) plotter.add_mesh(pyvista.Cube()) plotter.show() with pytest.raises(IndexError): # Test bad indices plotter = pyvista.Plotter(shape=(1, 2), off_screen=OFF_SCREEN) plotter.subplot(0, 0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(1, 0) plotter.add_mesh(pyvista.Cube()) plotter.show() # Test subplot 3 on left, 1 on right plotter = pyvista.Plotter(shape='3|1', off_screen=OFF_SCREEN) # First column plotter.subplot(0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(1) plotter.add_mesh(pyvista.Cube()) plotter.subplot(2) plotter.add_mesh(pyvista.Cylinder()) plotter.subplot(3) plotter.add_mesh(pyvista.Cone()) plotter.show() # Test subplot 3 on bottom, 1 on top plotter = pyvista.Plotter(shape='1|3', off_screen=OFF_SCREEN) # First column plotter.subplot(0) plotter.add_mesh(pyvista.Sphere()) plotter.subplot(1) plotter.add_mesh(pyvista.Cube()) plotter.subplot(2) plotter.add_mesh(pyvista.Cylinder()) plotter.subplot(3) plotter.add_mesh(pyvista.Cone()) plotter.show()
(slice(1, -1), 3) # Fourth group spans over rows 1-3 of the last column (3) ] plotter = pv.Plotter(shape=shape, row_weights=row_weights, col_weights=col_weights, groups=groups) # A grouped subplot can be activated through any of its composing cells using # the :func:`pyvista.BasePlotter.subplot` function. # Access all subplots and groups and plot something: plotter.subplot(0, 0) plotter.add_text("Group 1") plotter.add_mesh(pv.Cylinder(direction=[0, 1, 0], height=20)) plotter.view_yz() plotter.camera.Zoom(10) plotter.camera_set = True plotter.subplot(2, 0) plotter.add_text("Group 2") plotter.add_mesh(pv.ParametricCatalanMinimal(), show_edges=False, color="tan") plotter.view_isometric() plotter.camera.Zoom(2) plotter.camera_set = True plotter.subplot(2, 1) plotter.add_text("Group 3") plotter.add_mesh(examples.load_uniform(), show_edges=True)
def tri_cylinder(): """Triangulated cylinder""" return pyvista.Cylinder().triangulate()
def main(): datenow = datetime.datetime.now() datenow = datenow.strftime("%d/%m/%Y %H:%M:%S") sys.argv[0] = sys.argv[0].replace(" ", "\ ") start = time.perf_counter() # Write a log file log = open("nc_cryst.log", "a+") log_line = " ".join(sys.argv) log.write(datenow + " " + log_line + "\n") log.close() warnings.filterwarnings("ignore") # Disable ################################################################################## def blockPrint(): sys.stdout = open(os.devnull, 'w') # Restore def enablePrint(): sys.stdout = sys.__stdout__ def complementary(hex): """returns RGB components of complementary color""" hex = hex.lstrip('#') r, g, b = tuple(int(hex[i:i + 2], 16) for i in (0, 2, 4)) hsv = rgb_to_hsv(r, g, b) return (r / 255, g / 255, b / 255), tuple( np.array(hsv_to_rgb(((hsv[0] + 0.5) % 1), hsv[1], hsv[2])) / 255) def update_axes_label_color(axes_actor, color=None): """Set the axes label color (internale helper).""" if color is None: color = rcParams['font']['color'] color = parse_color(color) if isinstance(axes_actor, vtk.vtkAxesActor): prop_x = axes_actor.GetXAxisCaptionActor2D( ).GetCaptionTextProperty() prop_y = axes_actor.GetYAxisCaptionActor2D( ).GetCaptionTextProperty() prop_z = axes_actor.GetZAxisCaptionActor2D( ).GetCaptionTextProperty() for prop in [prop_x, prop_y, prop_z]: prop.SetColor(color[0], color[1], color[2]) prop.SetShadow(False) elif isinstance(axes_actor, vtk.vtkAnnotatedCubeActor): axes_actor.GetTextEdgesProperty().SetColor(color) return def create_axes_marker2(label_color=None, x_color=None, y_color=None, z_color=None, xlabel='a', ylabel='b', zlabel='c', labels_off=False, line_width=50): """Return an axis actor to add in the scene.""" if x_color is None: x_color = rcParams['axes']['x_color'] if y_color is None: y_color = rcParams['axes']['y_color'] if z_color is None: z_color = rcParams['axes']['z_color'] axes_actor = vtk.vtkAxesActor() axes_actor.GetXAxisShaftProperty().SetColor(parse_color(x_color)) axes_actor.GetXAxisTipProperty().SetColor(parse_color(x_color)) axes_actor.GetYAxisShaftProperty().SetColor(parse_color(y_color)) axes_actor.GetYAxisTipProperty().SetColor(parse_color(y_color)) axes_actor.GetZAxisShaftProperty().SetColor(parse_color(z_color)) axes_actor.GetZAxisTipProperty().SetColor(parse_color(z_color)) transform = vtk.vtkTransform() mat = transform.GetMatrix() latt_or = np.array(latt) latt_or[:, 0] = 2 * latt_or[:, 0] / np.linalg.norm(latt_or[:, 0]) latt_or[:, 1] = 2 * latt_or[:, 1] / np.linalg.norm(latt_or[:, 1]) latt_or[:, 2] = 2 * latt_or[:, 2] / np.linalg.norm(latt_or[:, 2]) for i in range(len(latt)): for j in range(len(latt)): mat.SetElement(i, j, 2 * latt_or[i, j]) axes_actor.SetUserTransform(transform) text = vtk.vtkTextProperty() text.SetFontSize(100) text.SetBold(True) text.SetFontFamilyAsString("Times") # Set labels axes_actor.SetXAxisLabelText(xlabel) axes_actor.SetYAxisLabelText(ylabel) axes_actor.SetZAxisLabelText(zlabel) axes_actor.SetNormalizedLabelPosition((1.3, 1.3, 1.3)) axes_actor.GetXAxisCaptionActor2D().SetCaptionTextProperty(text) axes_actor.GetYAxisCaptionActor2D().SetCaptionTextProperty(text) axes_actor.GetZAxisCaptionActor2D().SetCaptionTextProperty(text) if labels_off: axes_actor.AxisLabelsOff() # Set Line width axes_actor.GetXAxisShaftProperty().SetLineWidth(line_width) axes_actor.GetYAxisShaftProperty().SetLineWidth(line_width) axes_actor.GetZAxisShaftProperty().SetLineWidth(line_width) #axes_actor.SetNormalizedTipLength(1,1,1) #axes_actor.SetNormalizedShaftLength(2,2,2) update_axes_label_color(axes_actor, label_color) #axes_actor.SetNormalizedShaftLength(1.6,1.6,1.6) #axes_actor.SetNormalizedTipLength(0.4,0.4,0.4) #axes_actor.SetTotalLength(2,2,2) return axes_actor #atomic valency valency = np.array([ 1, 0, 1, 2, 3, 4, 5, 8, 1, 0, 1, 2, 3, 4, 5, 6, 6, 0, 1, 2, 3, 6, 5, 6, 7, 6, 5, 6, 4, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 4, 3, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 6, 6, 7, 2, 3, 4, 5, 6, 4, 7, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 6, 4, 5, 4, 4, 3, 3, 3, 4, 5, 6, 7, 8, 6, 6, 3, 2, 1, 2, 3, 4, 0, 8 ]) # Some functions track_r = np.array([[-10, -10, -10]]) def field_lines(point_grid): #ds=(V**(1/3))/N #ads=2/N mag_2 = [] N = 100 #ds=0.01 track_n = [] track_r = np.array([[-10, -10, -10]]) lines = np.zeros((2 * len(point_grid), N, 3)) mag = np.zeros((2 * len(point_grid), N)) j = -1 for o, r0 in enumerate(point_grid): F_old = [0, 0, 0] F_mag = 0 for one in [1, -1]: j += 1 xs = [] ys = [] zs = [] r = r0 for n in range(N): s = 0.01 xs.append(r[0]) ys.append(r[1]) zs.append(r[2]) lines[j, n, :] = r mag[j, n] = np.linalg.norm(F_mag) #mag.append(np.linalg.norm(F_mag)) #mag_2.append(np.linalg.norm(F_mag)) if nc_fort.is_close(track_r, r, len(track_r), 5e-3): break track_r = np.vstack((track_r, r)) if r[0] >= np.max(X) or r[0] <= np.min( X) or r[1] >= np.max(Y) or r[1] <= np.min( Y) or r[2] >= np.max(Z) or r[2] <= np.min(Z): break x, y, z = r try: vec_x = f_x([x, y, z]) except: vec_x = [0, 0, 0] try: vec_y = f_y([x, y, z]) except: vec_y = [0, 0, 0] try: vec_z = f_z([x, y, z]) except: vec_z = [0, 0, 0] F = np.array([vec_x[0], vec_y[0], vec_z[0]]) #line_gen(r) F_mag = F F = F / np.linalg.norm(F) phi = np.dot(F, F_old) phi = np.arccos(phi) / np.pi #print(n,phi) if np.round(phi, 4) == 1: break r = r + one * F * s F_old = F track_n.append(n) xs = np.array(xs) ys = np.array(ys) zs = np.array(zs) line_points = np.column_stack((xs, ys, zs)) return lines, mag, track_n ############################################################# #import matplotlib.pyplot as plt # LEFT BLANK ############################################################### ### ####### ###### # # # # # ## ##### #### ###### ##### # # # # # # # # # # # # # # # # ##### ###### # # # # #### ##### # # # # # # ###### ##### # # ##### # # # # # # # # # # # # # ### ####### # # # # # #### ###### # # ################################################################ # We want to read the parameters from a file called seed.nc_param # get from the commandline the seed parser = argparse.ArgumentParser( description= "Visualisation of cell structures and non-collinear magentic properties from a CASTEP job." ) parser.add_argument("seed", help="The seed from the CASTEP calculation.") parser.add_argument("-v", "--verbose", action="store_true", help="Turn on verbose output.") #parser.add_argument("-s","--sym",help="Tolerance for specifying reproduction of atoms outside unit cell (Ang)",default=1) parser.add_argument("-i", "--initmag", action="store_true", help="Plot initial magnetic moment vectors.") parser.add_argument( "-c", "--castep", action="store_true", help= "Read <seed>.castep file to determine moments. Only for NCM calculation (BETA)" ) parser.add_argument( "-f", "--field", help= "Read formatted potential or density to produce field. Only from VECTOR magnetic run.", action="store_true") parser.add_argument( "-o", "--orient", help= "Orientation of the crystal structure, takes values 'a,b,c,a*,b*,c*'.", default="sd") parser.add_argument("-B", "--bond", help="Set maximun bond length.", default=2.4) parser.add_argument("--save", help="Save image.", action="store_true") parser.add_argument("-d", "--delete", help="Delete atoms", nargs='+') parser.add_argument("-p", "--position", help="Camera position vector", nargs=6, default=np.array([0., 0., 0., 0., 0., 0.])) parser.add_argument( "-V", "--volumetric", help= "Provide file with volumetric data: .xsf .den_fmt .pot_fmt accepted.") parser.add_argument("-I", "--iso", help="Isosurface value for volumetric data", nargs="*") parser.add_argument("--colour", help="HEX code for Isosurface colouring", default="#0000FF") parser.add_argument("-z", "--zoom", help="Zoom multiplier", default=1) parser.add_argument("-e", "--exclude", help="Exclude atoms outside first unitcell", action="store_false") parser.add_argument( "-l", "--lines", help="Disable plotting of field lines of a provoded field line", action="store_true") parser.add_argument( "-P", "--plane", help= "Three points in fractional coordinates to define a plane for B-field.", nargs="*") parser.add_argument("-w", "--widget", help="Disable interactive widgets", action="store_false") parser.add_argument("-s", "--saturation", help="Saturation level for sections.", default=1) parser.add_argument("-S", "--spin", help="Plot spin isosurfaces from .den_fmt", action="store_true") parser.add_argument("-C", "--charge", help="Plot charge isosurfaces from .den_fmt", action="store_true") parser.add_argument( "-r", "--reduction", help= "Factor used to reduce the size of atoms, useful for visualising volumetric data without loss of context.", default=1.0) args = parser.parse_args() seed = args.seed #do_legend = args.legend do_verbose = args.verbose do_init_mag = args.initmag do_magmom = args.castep #do_Bfield=args.B_XC field = args.field #sym_tol=np.float(args.sym) orient = args.orient bond_cut = np.float(args.bond) save = args.save hide = args.delete cam_pos = args.position z = np.float(args.zoom) hide_lines = args.lines plane = args.plane exclude = args.exclude widgets = args.widget sat = np.float(args.saturation) docharge = args.charge dospin = args.spin reduction = np.float(args.reduction) iso = args.iso if plane == None: do_plane = False elif len(plane) == 9: do_plane = True elif len(plane) == 0: do_plane = True widgets = True else: print("Insufficient points provided for plane") sys.exit() if iso == None: do_iso = False elif len(iso) == 0: do_iso = True iso = None elif len(iso) > 1: print("Incorrect number of ISO arguments") sys.exit() else: do_iso = True # Make Charge the default if not docharge and not dospin: docharge = True if dospin: docharge = False xsf_file = args.volumetric hex_col = args.colour sym_tol = bond_cut for i in range(len(cam_pos)): cam_pos[i] = np.float(cam_pos[i]) if hide == None: hide = [""] # Define all the options (and the defaults) do_bonds = True #do_magmom = False #do_Bfield = False do_proj = False h = 0.5 #b_xc_file=seed+".B_xc.pot_fmt" xsffile = False denfile = False potfile = False noncollinear = False # Set iso surface colourmap iso_colours = complementary(hex_col) colors = list(iso_colours) colours = [colors[1], colors[0]] cmap_name = "iso_colors" cm = LinearSegmentedColormap.from_list(cmap_name, colours, N=2) # Open the tkinter window window = Tk() window.resizable(False, False) window.title("NC_CRYST: " + seed) output = Text(window) output.grid(row=1, column=0, columnspan=4) #,sticky=N+S+W) ################################################################## # Define all of the atom positions blockPrint() #if do_verbose: # print("Parsing .cell") cell = io.read(seed + ".cell") ccalc = Castep() ase_cell = cell.get_cell() a, b, c, alpha, beta, gamma = cell.get_cell_lengths_and_angles() pos = cell.get_positions() prim_pos = pos cell.set_calculator(ccalc) latt = np.transpose(np.matmul(np.identity(3), cell.get_cell())) init_mag = np.zeros((len(pos), 3)) init_spin = np.zeros((len(pos), 3)) if do_init_mag: try: with open(seed + ".cell") as init_cell: data = init_cell.readlines() except: print("No file: " + seed + ".cell") sys.exit() pos_i = [] counter = 0 for i in data: if "spin" in i.lower(): try: i = i.replace("=", " ") i = i.strip("\n") except: None i = i.split() if len(i) > 6: pos_i.append([np.float(j) for j in i[1:4]]) init_mag[counter] = [np.float(j) for j in i[5:8]] else: pos_i.append([np.float(j) for j in i[1:4]]) temp = [0., 0., np.float(i[5])] init_mag[counter] = temp counter += 1 init_spin = np.zeros((len(pos), 3)) sum_dat = "".join(data).lower() for i in range(len(pos_i)): for j in range(len(pos)): if "positions_frac" in sum_dat: dist = np.sum((np.matmul(latt, pos_i[i]) - pos[j])**2) if dist < 0.00001: init_spin[j] = init_mag[i] else: dist = np.sum((pos_i[i] - pos[j])**2) if dist < 0.00001: init_spin[j] = init_mag[i] cell.set_velocities(init_spin) # Make the supercell (gets all of the positions for me) scell = make_supercell(cell, 3 * np.identity(3)) pos = scell.get_positions() atoms = scell.get_atomic_numbers() symb = scell.get_chemical_symbols() Vol = cell.get_volume() enablePrint() #print(pos) atom_colours = jmol_colors[atoms] atom_radii = vdw_radii[atoms] inv_latt = np.linalg.inv(np.array(ase_cell.T)) init_spin = scell.get_velocities() #prim_count=0 #prim_list=np.zeros(len(pos),order="F") prim_count, prim_list, pos, keep, n_atoms, bonds, n_bonds = nc_fort.sym_positions( bond_cut, len(pos), pos, latt, inv_latt, exclude) prim_list = np.array(keep[0:prim_count]) #sys.exit() pos = pos[prim_list] atoms = atoms[prim_list] #pos=pos[prim_list] atom_radii = atom_radii[prim_list] atom_colours = atom_colours[prim_list] symb = np.array(symb)[prim_list] init_spin = init_spin[prim_list] unique_atom, atom_counts = np.unique(atoms, return_counts=True) atom_label = [] sort = [] ###################################### SYMMETRY POSITIONS ################### for j in unique_atom: for i in range(len(cell.get_atomic_numbers())): if atoms[i] == j: sort.append(i) sort = np.array(sort) if do_magmom: with open(seed + ".castep") as castep: castep_lines = castep.readlines() for no, test in enumerate(castep_lines): if "Noncollinear Spin Vectors" in test: line_no = no mom_vec = [] vec_symb = [] for i in range(line_no + 4, line_no + 4 + len(prim_pos)): cline = castep_lines[i] cline = cline.split() vec = [np.float(cline[2]), np.float(cline[3]), np.float(cline[4])] vec_symb.append(cline[0]) mom_vec.append(vec) #print(mom_vec) vec_symb_2 = list(vec_symb) mom_vec_2 = list(mom_vec) for i in range(len(sort)): vec_symb_2[sort[i]] = vec_symb[i] mom_vec_2[sort[i]] = mom_vec[i] vec_symb = list(vec_symb_2) mom_vec = list(mom_vec_2) if do_magmom: ccell = cell.copy() ccell.set_velocities(mom_vec) ccell = make_supercell(ccell, 3 * np.identity(3)) mom_vec = ccell.get_velocities() sort = np.argsort(atoms) atoms = atoms[sort] pos = pos[sort] atom_radii = atom_radii[sort] atom_colours = atom_colours[sort] symb = np.array(symb)[sort] if do_init_mag: init_spin = init_spin[sort] if do_magmom: mom_vec = np.array(mom_vec) mom_vec = mom_vec[sort] for i in atom_counts: for j in range(i): atom_label.append(j + 1) hide_num = [] for i in range(len(symb)): for j in hide: if j == symb[i]: hide_num.append(i) # Time for some plotting pv.set_plot_theme("document") if save: p = pv.Plotter(off_screen=True) else: p = pv.Plotter() p.enable_parallel_projection() orientation = [latt[:, 0], latt[:, 1], latt[:, 2]] for i in range(3): orientation[i] = orientation[i] / 2 * np.linalg.norm(orientation[i]) arrow_or=pv.Arrow([0,0,0],orientation[0],tip_length=0.25, tip_radius=0.09, tip_resolution=20, shaft_radius=0.03, shaft_resolution=20) +\ pv.Arrow([0,0,0],orientation[1],tip_length=0.25, tip_radius=0.09, tip_resolution=20, shaft_radius=0.03, shaft_resolution=20) +\ pv.Arrow([0,0,0],orientation[2],tip_length=0.25, tip_radius=0.09, tip_resolution=20, shaft_radius=0.03, shaft_resolution=20)+\ pv.Sphere(0.1,[0,0,0]) test = create_axes_marker2(label_color="black", line_width=4, x_color="r", y_color="g", z_color="b", xlabel="a", ylabel="b", zlabel="c", labels_off=False) p.add_orientation_widget(test) ######################################################################################################################## # _______ _ _ _ ______ _ _ _ #(_______|_) | | | | / _____) | | | | _ (_) # _____ _ ____| | _ | | | / ____| | ____ _ _| | ____| |_ _ ___ ____ ___ #| ___) | |/ _ ) |/ || | | | / _ | |/ ___) | | | |/ _ | _)| |/ _ \| _ \ /___) #| | | ( (/ /| ( (_| | | \____( ( | | ( (___| |_| | ( ( | | |__| | |_| | | | |___ | #|_| |_|\____)_|\____| \______)_||_|_|\____)\____|_|\_||_|\___)_|\___/|_| |_(___/ ######################################################################################################################## if xsf_file != None: # See what sort of file we have. if ".den_fmt" in xsf_file: denfile = True elif ".pot_fmt" in xsf_file: potfile = True elif ".xsf" in xsf_file: xsffile = True nx, ny, nz, mesh_mag = xsf.read_xsf(xsf_file) if potfile: docharge = False dospin = False if potfile or denfile: with open(xsf_file) as header: data = header.readlines()[0:11] nx, ny, nz = data[8].split()[0:3] nx, ny, nz = int(nx), int(ny), int(nz) #latt=np.array([data[3].split()[0:3],data[4].split()[0:3],data[5].split()[0:3]]).astype(float) #latt=np.transpose(latt) V = np.loadtxt(xsf_file, skiprows=11) #n= np.round(h*nz) #mask=(V[:,2] == n ) V3D = V #V=V[mask] if potfile: if np.shape(V3D)[1] == 9: noncollinear = True V1 = V3D[:, 3] + 1j * V3D[:, 4] V2 = V3D[:, 5] + 1j * V3D[:, 6] V3 = V3D[:, 7] + 1j * V3D[:, 8] B_x = np.real((V3 + np.conj(V3)) / 2) B_y = np.real(1j * (V3 - np.conj(V3)) / 2) B_z = np.real((V1 - V2) / 2) else: noncollinear = False print("3D data only accepted for NCM .pot_fmt, Exiting...") sys.exit() if denfile: if np.shape(V3D)[1] == 7: noncollinear = True B_x = V3D[:, 4] B_y = V3D[:, 5] B_z = V3D[:, 6] charge = V3D[:, 3] mesh_mag = np.zeros((nx, ny, nz)) if docharge: for i in range(len(V3D)): mesh_mag[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = charge[i] else: noncollinear = False charge = V3D[:, 3] spin = V3D[:, 4] mesh_mag = np.zeros((nx, ny, nz)) if docharge: for i in range(len(V3D)): mesh_mag[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = charge[i] if dospin: for i in range(len(V3D)): mesh_mag[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = spin[i] mesh_mag = mesh_mag / (nx * ny * nz) #print("NCM: ",noncollinear) #print("POT: ",potfile) #print("DEN: ",denfile) #print("Charge: ",docharge) #print("Spin: ",dospin) if noncollinear and not docharge: mesh3D_x = np.zeros((nx, ny, nz)) mesh3D_y = np.zeros((nx, ny, nz)) mesh3D_z = np.zeros((nx, ny, nz)) for i in range(len(V3D)): mesh3D_x[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = B_x[i] mesh3D_y[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = B_y[i] mesh3D_z[int(V3D[i, 0] - 1), int(V3D[i, 1] - 1), int(V3D[i, 2] - 1)] = B_z[i] mesh_mag = np.sqrt(mesh3D_x**2 + mesh3D_y**2 + mesh3D_z**2) # Calcuate the Div x_flux = np.sum(mesh3D_x[0:-1, 0, 0]) - np.sum(mesh3D_x[0:-1, -1, -1]) y_flux = np.sum(mesh3D_x[0, 0:-1, 0]) - np.sum(mesh3D_x[-1, 0:-1, -1]) z_flux = np.sum(mesh3D_x[0, 0, 0:-1]) - np.sum(mesh3D_x[-1, -1, 0:-1]) flux = x_flux + y_flux + z_flux # Play here might cause asymmetry Vx = (V[:, 0] - 1) / (nx) Vy = (V[:, 1] - 1) / (ny) Vz = (V3D[:, 2] - 1) / (nz) # Set up for fieldlines calc X = np.linspace(np.min(Vx), np.max(Vx), nx, endpoint=True) Y = np.linspace(np.min(Vy), np.max(Vy), ny, endpoint=True) Z = np.linspace(np.min(Vz), np.max(Vz), nz, endpoint=True) f_x = RegularGridInterpolator((X, Y, Z), mesh3D_x) f_y = RegularGridInterpolator((X, Y, Z), mesh3D_y) f_z = RegularGridInterpolator((X, Y, Z), mesh3D_z) #X,Y=np.meshgrid(X,Y) n_grid = 175 ix = int(np.round(a / np.cbrt(Vol / n_grid))) iy = int(np.round(b / np.cbrt(Vol / n_grid))) iz = int(np.round(c / np.cbrt(Vol / n_grid))) if ix == 0: ix = 1 if iy == 0: iy = 1 if iz == 0: iz = 1 #sys.exit() #ix,iy,iz=[8,8,3] N = 500 k = 0.5 x = np.linspace(0.1, 0.9, ix, endpoint=True) y = np.linspace(0.1, 0.9, iy, endpoint=True) z = np.linspace(0.1, 0.9, iz, endpoint=True) gx, gy, gz = np.meshgrid(x, y, z) gx = gx.reshape(ix * iy * iz) gy = gy.reshape(ix * iy * iz) gz = gz.reshape(ix * iy * iz) point_grid = np.zeros((ix * iy * iz, 3)) point_grid[:, 0] = gx point_grid[:, 1] = gy point_grid[:, 2] = gz if field: #for m,gpoint in enumerate(point_grid): #i,j,k=gpoint # track_r=field_lines(np.array([i,j,k]),track_r)#map[m][0:counter[m]]) lines, mags, n_track = field_lines(point_grid) mags = np.power(mags, 0.45) #mags=mags/np.max(mags) for k in range(2 * len(point_grid)): if n_track[k] > 1: line_points = lines[k, 0:n_track[k], :] mag = mags[k, 0:n_track[k]] line_points = nc_fort.multmatmul( latt, line_points, len(line_points)) mag[0] = mag[1] #mag=mag/np.max(mag) #mag[mag<0.3*np.max(mag)]=0#0.5*np.max(mag) r = 0.008 polyLine = pv.PolyData(line_points) polyLine.points = line_points polyLine["scalars"] = np.array(mag) theCell = np.arange(0, len(line_points), dtype=np.int) theCell = np.insert(theCell, 0, len(line_points)) polyLine.lines = theCell tube = polyLine.tube(radius=r) #p.add_mesh(tube,color="black", smooth_shading=True) p.add_mesh( tube, show_scalar_bar=False, cmap="gist_yarg", opacity=mag, pickable=False ) #,color="black")#cmap='binary',opacity=mag) #Flatten the mesh if not xsffile: mesh_mag = mesh_mag.flatten('F') else: mesh_mag = mesh_mag.flatten('C') #if not xsffile: xs = np.linspace(0, 1, nx, endpoint=True) ys = np.linspace(0, 1, ny, endpoint=True) zs = np.linspace(0, 1, nz, endpoint=True) points = np.zeros((mesh_mag.shape[0], 3)) counter = 0 for z in zs: for y in ys: for x in xs: points[counter, :] = np.matmul(latt, [x, y, z]) counter += 1 sgrid = pv.StructuredGrid() sgrid.points = points sgrid.dimensions = [nx, ny, nz] sgrid.point_arrays["values"] = mesh_mag if do_plane: # calculate the vectors if len(plane) > 1: plane = nc_fort.multmatmul(latt, plane, 3) v1 = plane[0] - plane[1] v2 = plane[0] - plane[2] print(v1, v2) norm = np.cross(v1, v2) if np.linalg.norm(norm) == 0: print("Plane vectors colinear: Exiting...") sys.exit() v2 = np.cross(norm, v1) cmap = "autumn" #"plasma" if save or len(plane) > 1: slice = sgrid.slice(norm, plane[0]) val = slice.point_arrays["values"] p.add_mesh(slice, cmap=cmap, show_scalar_bar=False, clim=(np.min(val), sat * np.max(val)), pickable=False) else: p.add_mesh_slice(sgrid, show_scalar_bar=False, cmap=cmap, show_edges=False, implicit=False, clim=(np.min(mesh_mag), sat * np.max(mesh_mag)), pickable=False) if do_iso: if iso == None: iso = 0.05 * np.max([np.max(mesh_mag), abs(np.min(mesh_mag))]) else: iso = np.float(iso[0]) output.insert(END, "VOLUMETRIC\n") output.insert(END, "----------\n") output.insert( END, "Max: " + str(np.max(mesh_mag)) + " Min: " + str(np.min(mesh_mag)) + "\n") output.insert(END, "Isovalue: " + str(iso) + "\n") output.insert(END, " \n") if save or not widgets: contours = sgrid.contour([iso, -iso]) slider_contour = p.add_mesh(contours, opacity=0.4, cmap=cm, smooth_shading=True, show_scalar_bar=False, lighting=True, name="contour", pickable=False) else: def cont(iso_val): contours = sgrid.contour([iso_val, -iso_val]) slider_contour = p.add_mesh(contours, opacity=0.4, cmap=cm, smooth_shading=True, show_scalar_bar=False, lighting=True, name="contour", pickable=False) return p.add_slider_widget(cont, rng=(np.min(mesh_mag), np.max(mesh_mag)), value=iso, style="modern", title="Isosurface Value", pointa=(0.1, 0.9), pointb=(0.3, 0.9)) ######################################################################################################################## ######################################################################################################################## ######################################################################################################################## ######################################################################################################################## ######################################################################################################################## ######################################################################################################################## # Add the box edges = np.array([[[0., 0., 0.], [0., 0., 1.]], [[0., 0., 0.], [0., 1., 0.]], [[0., 0., 0.], [1., 0., 0.]], [[1., 1., 1.], [1., 0., 1.]], [[1., 1., 1.], [1., 1., 0.]], [[1., 1., 1.], [0., 1., 1.]], [[0., 1., 1.], [0., 0., 1.]], [[0., 1., 1.], [0., 1., 0.]], [[1., 1., 0.], [1., 0., 0.]], [[1., 1., 0.], [0., 1., 0.]], [[1., 0., 0.], [1., 0., 1.]], [[0., 0., 1.], [1., 0., 1.]]]) for i, main in enumerate(edges): for j, sub in enumerate(main): edges[i, j] = np.matmul(latt, sub) box = pv.Box([0, 1, 0, 1, 0, 1]) for i in range(0, 12): p.add_lines(edges[i], color="black", width=1.5) # Do the atoms for i, vec in enumerate(pos): if i in hide_num: continue sphere = pv.Sphere(atom_radii[i] / (reduction * 5), vec, theta_resolution=200, phi_resolution=200) p.add_mesh(sphere, color=atom_colours[i], specular=0.3, specular_power=30, ambient=0.2, diffuse=1, pickable=True) def pick_atom(actor, two): if actor != None: centre = actor.center #np.matmul(np.linalg.inv(latt),actor.center) for i in range(len(pos)): if (np.isclose(pos[i], centre)).all(): break vec = np.round(np.matmul(np.linalg.inv(latt), pos[i]), 4) string = "Atom " + str(i) + ":" + " " + symb[i] + " (" + str( vec[0]) + " , " + str(vec[1]) + " , " + str(vec[2]) + ")\n" #print(string) output.insert(END, string) #p.enable_cell_picking(through=True,callback=pick_atom,show_message=False,use_mesh=True) p.enable_point_picking(callback=pick_atom, use_mesh=True, show_message=False, show_point=False) p.window_size = 1000, 1000 p.store_image = True # Do the bonds #print("No. atoms: ",len(atoms)) output.insert(END, "No. atoms: " + str(len(atoms)) + "\n") if do_bonds: bond_length = [] bond_name = [] bond_ind = [] bonds = np.zeros(len(atoms)) for atom1 in range(len(pos)): for atom2 in range(atom1, len(pos)): dist = np.sqrt(np.sum((pos[atom1] - pos[atom2])**2)) if dist > 0 and dist < bond_cut: bond_length.append(dist) bond_name.append(symb[atom1] + str(atom_label[atom1]) + "-" + symb[atom2] + str(atom_label[atom2])) bond_ind.append([atom1, atom2]) bonds[atom1] += 1 bonds[atom2] += 1 bond_length = np.array(bond_length) valence = valency[atoms - 1] over = -valence + bonds pop = [] for atom in range(len(over)): if over[atom] <= 0: continue atom_loc = [] for n, i in enumerate(bond_ind): if atom == i[0] or atom == i[1]: atom_loc.append(n) lengths = bond_length[atom_loc] loc = np.argsort(lengths)[-int(over[atom]):] for i in loc: pop.append(atom_loc[i]) bond_length = list(bond_length) pop = np.flip(np.unique(pop)) for pi in pop: bond_length.pop(pi) bond_name.pop(pi) bond_ind.pop(pi) for i, index in enumerate(bond_ind): i, j = index if i in hide_num or j in hide_num: continue points = np.array([pos[i], (pos[j] + pos[i]) / 2]) direc = points[0] - points[1] mid = (points[1] + points[0]) / 2 height = np.sqrt(np.sum((points[0] - points[1])**2)) cyl = pv.Cylinder(mid, direc, np.min(atom_radii) / 20, height) p.add_mesh(cyl, color=atom_colours[i], pickable=False) points = np.array([pos[j], (pos[j] + pos[i]) / 2]) direc = points[0] - points[1] mid = (points[1] + points[0]) / 2 height = np.sqrt(np.sum((points[0] - points[1])**2)) cyl = pv.Cylinder(mid, direc, np.min(atom_radii) / 20, height) p.add_mesh(cyl, color=atom_colours[j], specular=0.3, specular_power=30, ambient=0.2, diffuse=1, pickable=False) #for i in bond_name: # print(i) if do_magmom: for i in range(len(pos)): if i in hide_num: continue temp_pos = pos[i] - np.array(mom_vec[i]) / 2 arrow = pv.Arrow(temp_pos, mom_vec[i], tip_length=0.15, tip_radius=0.09, tip_resolution=20, shaft_radius=0.04, shaft_resolution=20, scale='auto') p.add_mesh(arrow, color='b', pickable=False) if do_init_mag: for i in range(len(pos)): if i in hide_num: continue temp_pos = pos[i] - np.array(1.5 * init_spin[i]) / 2 arrow = pv.Arrow(temp_pos, 1.5 * init_spin[i], tip_length=0.15, tip_radius=0.09, tip_resolution=20, shaft_radius=0.04, shaft_resolution=20, scale='auto') p.add_mesh(arrow, color='g', pickable=False) try: p.camera.zoom(z) except: output.insert(END, "Zoom not implemented in this version of PyVista.\n") #print("Zoom not implemented in this version of PyVista.") ############################################################################################### def screenshot(): wind = p.window_size height = 2560 p.window_size = [ height, int(height * p.window_size[1] / p.window_size[0]) ] p.save_graphic(seed + ".eps") p.window_size = wind if do_verbose: output.insert(END, "Graphic saved!\n") p.add_key_event("s", screenshot) def perpendicular(a): b = np.empty_like(a) b[0] = -a[1] b[1] = a[0] return b # calculate the reciprocal lattice vectors a1 = latt[:, 0] a2 = latt[:, 1] a3 = latt[:, 2] b1 = np.cross(a2, a3) b2 = np.cross(a3, a1) b3 = np.cross(a1, a2) focus = np.matmul(latt, np.array([0.5, 0.5, 0.5])) if orient != None: cp = p.camera_position if orient == 'a': o = a3 vpvec = a1 / np.linalg.norm(a1) elif orient == 'a*': o = a3 vpvec = b1 / np.linalg.norm(b1) elif orient == 'b': o = a3 vpvec = a2 / np.linalg.norm(a2) elif orient == 'b*': o = a3 vpvec = b2 / np.linalg.norm(b2) elif orient == 'c': o = a2 vpvec = a3 / np.linalg.norm(a3) elif orient == 'c*': o = a2 vpvec = b3 / np.linalg.norm(b3) elif orient == "sd": o = a3 #T=[latt[i,i] for i in range(0,3)] T = 0.9 * a1 + 0.4 * a2 + 0.1 * a3 vpvec = T / np.linalg.norm(T) vp = focus + 15 * vpvec p.camera_position = [vp, focus, o] if np.sum(cam_pos) != 0: v = (cam_pos[0], cam_pos[1], cam_pos[2]) o = (cam_pos[3], cam_pos[4], cam_pos[5]) p.camera_position = [v, focus, o] def button_sd(): o = a3 T = 0.9 * a1 + 0.4 * a2 + 0.1 * a3 vpvec = T / np.linalg.norm(T) vp = focus + 15 * vpvec p.camera_position = [vp, focus, o] def button_a(): o = a3 vpvec = a1 / np.linalg.norm(a1) vp = focus + 15 * vpvec p.camera_position = [vp, focus, o] def button_b(): o = a3 vpvec = a2 / np.linalg.norm(a2) vp = focus + 15 * vpvec p.camera_position = [vp, focus, o] def button_c(): o = a2 vpvec = a3 / np.linalg.norm(a3) vp = focus + 15 * vpvec p.camera_position = [vp, focus, o] end = time.perf_counter() p.add_key_event("o", button_sd) p.add_key_event("a", button_a) p.add_key_event("b", button_b) p.add_key_event("c", button_c) output.insert(END, "Time: " + str(np.round(end - start, 4)) + " s\n") if save: p.window_size = [5000, 5000] #p.save_graphic(seed+".pdf") p.show(title=seed, screenshot=seed + ".png") else: p.show(title=seed) if do_verbose: print("Final Camera Position:") print(p.camera_position[0][0], p.camera_position[0][1], p.camera_position[0][2], p.camera_position[2][0], p.camera_position[2][1], p.camera_position[2][2]) sys.exit() window.mainloop()
# by data on its nodes, the values must be interpolated across the faces of # cells. The process by which those scalars are interpolated is critical. # If the ``interpolate_before_map`` is left off, the color mapping occurs at # polygon points and colors are interpolated, which is generally less accurate # whereas if the ``interpolate_before_map`` is on, then the scalars will be # interpolated across the topology of the dataset which is more accurate. # # To summarize, when ``interpolate_before_map`` is off, the colors are # interpolated after rendering and when ``interpolate_before_map`` is on, the # scalars are interpolated across the mesh and those values are mapped to # colors. # # So lets take a look at the difference: # Load a cylider which has cells with a wide spread cyl = pv.Cylinder(direction=(0, 0, 1), height=2).elevation() # Common display argument to make sure all else is constant dargs = dict(scalars='Elevation', cmap='rainbow', show_edges=True) p = pv.Plotter(shape=(1, 2)) p.add_mesh(cyl, interpolate_before_map=False, stitle='Elevation - not interpolated', **dargs) p.subplot(0, 1) p.add_mesh(cyl, interpolate_before_map=True, stitle='Elevation - interpolated', **dargs) p.link_views()
.. _ref_geometric_example: Geometric Objects ~~~~~~~~~~~~~~~~~ The "Hello, world!" of VTK """ import pyvista as pv ############################################################################### # This runs through several of the available geometric objects available in # VTK which PyVista provides simple convenience methods for generating. # # Let's run through creating a few geometric objects! cyl = pv.Cylinder() arrow = pv.Arrow() sphere = pv.Sphere() plane = pv.Plane() line = pv.Line() box = pv.Box() cone = pv.Cone() poly = pv.Polygon() disc = pv.Disc() ############################################################################### # Now let's plot them all in one window p = pv.Plotter(shape=(3, 3)) # Top row p.subplot(0, 0)
# But by using a ``dict``, it is possible to modify the properties of the # outline. For example, color and width could be specified like so: plotter = pyvista.Plotter() silhouette = dict( color='red', line_width=8.0, ) plotter.add_mesh(bunny, silhouette=silhouette) plotter.view_xy() plotter.show() ############################################################################### # By default, PyVista uses a pretty aggressive decimation level but we might # want to disable it. It is also possible to display sharp edges: cylinder = pyvista.Cylinder(center=(0, 0.04, 0), direction=(0, 1, 0), radius=0.15, height=0.03).triangulate() plotter = pyvista.Plotter(shape=(1, 3)) plotter.subplot(0, 0) plotter.add_mesh(cylinder, color='tan', smooth_shading=True, silhouette=dict( color='red', line_width=8.0, decimate=None, feature_angle=True)) plotter.add_text("Silhouette with sharp edges") plotter.view_isometric() plotter.subplot(0, 1) plotter.add_mesh(cylinder, color='tan', smooth_shading=True, silhouette=dict( color='red',
def generatePutOption(p, putPos=3, size=6, zPos=0, showText=True): axis3D = np.array([1, 0, 0]) yPos = -1 # Plot the arrow at the bottom signifying the # time of expiry if size < 2: yPos = -2 arrow1 = pv.Arrow(start=([size - 1., yPos, 0]), direction=axis3D, tip_length=0.5, tip_radius=0.15, shaft_radius=.025) arrow2 = pv.Arrow(start=([1, yPos, 0]), direction=axis3D * -1, tip_length=0.5, tip_radius=0.15, shaft_radius=.025) axis1 = pv.Cylinder(radius=0.025, direction=axis3D, center=np.array([0.5 * size, yPos, 0]), height=size, resolution=100) p.add_point_labels([(size / 2, yPos - 1, 0)], ['time to expiry'], font_family='times', font_size=20, fill_shape=False, shape=None, bold=False, text_color='#aeb6bf', show_points=False, point_size=0, point_color=(0.3, 0.3, 0.3)) p.add_mesh(arrow1, color='#aeb6bf') p.add_mesh(arrow2, color='#aeb6bf') p.add_mesh(axis1, color='#aeb6bf') # Dashed lines for various purposes ... dashSize = 0.1 spaceSize = 0.05 yPos = 5 # Horizontal blue line for i in np.linspace(0, 10, int(10 / (dashSize + spaceSize))): cyl = pv.Cylinder(radius=0.025, direction=axis3D, center=np.array([i + dashSize / 2, yPos, 0]), height=dashSize, resolution=100) p.add_mesh(cyl, color='#3498db') # vertical line for i in np.linspace(0, 10, int(10 / (dashSize + spaceSize))): cyl = pv.Cylinder(radius=0.025, direction=axis3D, center=np.array([size, i + dashSize / 2, 0]), height=dashSize, resolution=100) p.add_mesh(cyl, color='#aeb6bf') # Put option line for i in np.linspace(0, size, int(size / (dashSize + spaceSize))): cyl = pv.Cylinder(radius=0.025, direction=axis3D, center=np.array([i + dashSize / 2, putPos, zPos]), height=dashSize, resolution=100) p.add_mesh(cyl, color='#abebc6') if zPos != 0: for i in np.linspace(0, size, int(size / (dashSize + spaceSize))): cyl = pv.Cylinder(radius=0.025, direction=axis3D, center=np.array([i + dashSize / 2, putPos, 0]), height=dashSize, resolution=100) p.add_mesh(cyl, color='#abebc6') plane = pv.Plane(center=(size / 2, putPos / 2, zPos), direction=(0, 0, 1), i_size=size, j_size=putPos) plane['scalars'] = np.ones(plane.n_points) p.add_mesh(plane, color='#abebc6', opacity=0.1, show_edges=True, edge_color='#abebc6') if showText: p.add_point_labels([(size / 2, putPos / 2, 0)], ['buyer makes money here'], font_family='times', font_size=20, fill_shape=False, shape=None, bold=False, text_color='#85929e', show_points=False, point_size=0, point_color=(0.3, 0.3, 0.3)) p.add_point_labels([(-3, putPos - 0.25, 0)], ['buy put'], font_family='times', font_size=20, fill_shape=False, shape=None, bold=False, text_color='#85929e', show_points=False, point_size=0, point_color=(0.3, 0.3, 0.3)) return
def test_cylinder(): surf = pyvista.Cylinder([0, 10, 0], [1, 1, 1], 1, 5) assert np.any(surf.points) assert np.any(surf.faces)
def main(): # Begin trating arguments parser = argparse.ArgumentParser( description='Display the calcuated data of IMS calculations.') parser.add_argument('--showstat', action='store_true', help='Show statistics') parser.add_argument('--open3d', action='store_false', help='Turn on open3d rendering') parser.add_argument('--mate', action='store_true', help='Turn on mate rendering') parser.add_argument('--colormode', '-c', type=str, default="auto", help='Color mode: auto|iso. default: %(default)s') parser.add_argument( '--representation', '-r', type=str, default="cloud", help='Representation mode: cloud|surface. default: %(default)s') parser.add_argument('--shot', action='store_true', help='Save a picture') parser.add_argument('--twopanels', '-2', action='store_true', help='Show the molecule') parser.add_argument('--molecule', '-m', action='store_true', help='Show the molecule') args = parser.parse_args() showstat = args.showstat colormode = args.colormode mate = args.mate representation = args.representation molecule = args.molecule open3d = args.open3d twopanels = args.twopanels shot = args.shot # End trating arguments # Read ims.dat # The ims.dat format is: # x, y, z, nx, ny, nz, val #skirow does not read the first line values = np.loadtxt("ims.dat", delimiter=",", skiprows=1) if showstat: a = np.hstack(values[:, 6]) _ = plt.hist(a, bins='auto') # arguments are passed to np.histogram plt.title("Repartition of IMS values") plt.show() geom = geometry.geometry.Geometry("geom.xyz") if open3d: pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(values[:, :3]) pcd.normals = o3d.utility.Vector3dVector(values[:, 3:6]) spheres = [] mesh_molecule = None #generate molecule in open3D format if molecule: for at in geom.atoms: mat = [[1, 0, 0, at['x']], [0, 1, 0, at['y']], [0, 0, 1, at['z']], [0, 0, 0, 1]] mesh_sphere = o3d.geometry.TriangleMesh.create_sphere( radius=0.4) mesh_sphere.transform(mat) mesh_sphere.compute_vertex_normals() if at['label'] == 'C': color = [0.4, 0.4, 0.4] elif at['label'] == 'H': color = [0.9, 0.9, 0.9] else: color = [1.0, 0.0, 0.0] mesh_sphere.paint_uniform_color(color) spheres.append(mesh_sphere) cylinders = [] molecularGraph = graph_theory.detect_cycle.MolecularGraph( "geom.xyz") for e in molecularGraph.getEdges(): idx1 = e.GetBeginAtomIdx() idx2 = e.GetEndAtomIdx() at1 = geom.getAtom(idx1) at2 = geom.getAtom(idx2) pos1 = np.asarray([at1['x'], at1['y'], at1['z']]) pos2 = np.asarray([at2['x'], at2['y'], at2['z']]) vect_bond = pos2 - pos1 middle_bond = 0.5 * (pos1 + pos2) mat_translation = np.asarray([[1, 0, 0, middle_bond[0]], [0, 1, 0, middle_bond[1]], [0, 0, 1, middle_bond[2]], [0, 0, 0, 1]]) # print(mat_translation) vect_axis = np.cross( vect_bond, [0, 0, 1]) #cylinders are aligne along z when created theta = np.arcsin( np.linalg.norm(vect_axis) / np.linalg.norm(vect_bond)) vect_axis = vect_axis / np.linalg.norm(vect_axis) ux = vect_axis[0] uy = vect_axis[1] uz = vect_axis[2] c = np.cos(theta) s = np.sin(theta) mat_rotation = np.asarray([[ ux * ux * (1 - c) + c, ux * uy * (1 - c) - uz * s, ux * uz * (1 - c) + uy * s, 0 ], [ ux * uy * (1 - c) + uz * s, uy * uy * (1 - c) + c, uy * uz * (1 - c) - ux * s, 0 ], [ ux * uz * (1 - c) - uy * s, uy * uz * (1 - c) + ux * s, uz * uz * (1 - c) + c, 0 ], [0, 0, 0, 1]]) mesh_cylinder = o3d.geometry.TriangleMesh.create_cylinder( radius=.2, height=np.linalg.norm(vect_bond)) mesh_cylinder.transform(mat_rotation) mesh_cylinder.transform(mat_translation) mesh_cylinder.compute_vertex_normals() mesh_cylinder.paint_uniform_color([0.0, 0.6, 1.0]) cylinders.append(mesh_cylinder) mesh_molecule = spheres mesh_molecule.extend(cylinders) # end generate molecule in open3D format point_rgb = valtoRGB(values[:, 6], colormode=colormode) pcd.colors = o3d.utility.Vector3dVector(np.asarray(point_rgb)) if representation == 'cloud': if molecule: o3d.visualization.draw_geometries([pcd] + mesh_molecule) else: o3d.visualization.draw_geometries([pcd]) poisson_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson( pcd, depth=9)[0] if not (mate): poisson_mesh.compute_vertex_normals() density_mesh = o3d.geometry.TriangleMesh() if representation == 'surface': if molecule: vis = o3d.visualization.draw_geometries([poisson_mesh] + mesh_molecule) else: vis = o3d.visualization.draw_geometries([poisson_mesh]) o3d.io.write_triangle_mesh("./surface_mesh.ply", poisson_mesh) else: #begin pysta points = values[:, :3] data = values[:, 6] points = pv.pyvista_ndarray(points) datac = pv.pyvista_ndarray(data) point_cloud = pv.PolyData(points) point_cloud["IMS"] = datac cloud = pv.wrap(point_cloud) cloud.save('test.vtk', binary=False) # cloud.save('test_asc.vtk', binary=False) # cloud.save('test_bin.vtk', binary=True) alpha = 1 superred = np.array([1, 1, 0, alpha]) red = np.array([1, 0, 0, alpha]) darkred = np.array([1, .25, .25, alpha]) lightred = np.array([1, .75, .75, alpha]) lightblue = np.array([1, .75, .75, alpha]) darkblue = np.array([1, .25, .25, alpha]) blue = np.array([1, 0, 0, alpha]) purple = np.array([1, 0, 1, alpha]) mapping = np.linspace(datac.min(), datac.max(), 256) newcolors = np.empty((256, 4)) newcolors[mapping < 40] = superred newcolors[mapping < 30] = red newcolors[mapping < 20] = darkred newcolors[mapping < 10] = lightred newcolors[mapping < -10] = lightblue newcolors[mapping < -20] = darkblue newcolors[mapping < -30] = blue newcolors[mapping <= -40] = purple my_colormap = ListedColormap(newcolors) #Palette (1) ACIE Karadakov: p1_level_1 = np.array([1, 0.9, 0.8, alpha]) # Pale Brown p1_level_2 = np.array([0.6, 0.7, 0.95, alpha]) # Clear blue p1_level_3 = np.array([0, 0.4, 0.85, alpha]) # Clear blue but no so clear p1_level_4 = np.array([0, 0, 1, alpha]) #Plain blue p1_level_5 = np.array([0, 0, 0.4, alpha]) # Noir blue #Palette (2) Yellow to blue: p2_level_1 = np.array([1, 0.5, 0, alpha]) # Orange p2_level_2 = np.array([1, 1, 0, alpha]) # Yellow p2_level_3 = np.array([0, 1, 0, alpha]) # Green p2_level_4 = np.array([0, 0, 1, alpha]) # Blue p2_level_5 = np.array([1, 0, 1, alpha]) # "Noir blue #Palette (3) The Oranges: p3_level_1 = np.array([1, 0.9, 0.75, alpha]) # White Orange p3_level_2 = np.array([1, 0.75, 0.5, alpha]) # Clear Orange p3_level_3 = np.array([1, 0.6, 0.25, alpha]) # Pale Orange p3_level_4 = np.array([1, 0.5, 0, alpha]) # Orange p3_level_5 = np.array([0.5, 0.25, 0, alpha]) # Dark Orange #Palette (4) The Reds: p4_level_1 = np.array([1, 0.8, 0.8, alpha]) # White Red p4_level_2 = np.array([1, 0.6, 0.6, alpha]) # Clear Red p4_level_3 = np.array([1, 0.2, 0.2, alpha]) # Pale Red p4_level_4 = np.array([1, 0, 0, alpha]) # Red p4_level_5 = np.array([0.5, 0, 0, alpha]) # Dark Red #Palette (5) The Greens: p5_level_1 = np.array([0.8, 1, 0.8, alpha]) # White Green p5_level_2 = np.array([0.6, 1, 0.6, alpha]) # Clear Green p5_level_3 = np.array([0.4, 1, 0.4, alpha]) # Pale Green p5_level_4 = np.array([0, 1, 0, alpha]) # Green p5_level_5 = np.array([0, 0.25, 0, alpha]) # Dark Green #Palette (6) The Purples: p6_level_1 = np.array([1, 0.8, 1, alpha]) # White Purple p6_level_2 = np.array([1, 0.6, 1, alpha]) # Clear Purple p6_level_3 = np.array([1, 0.4, 1, alpha]) # Pale Purple p6_level_4 = np.array([1, 0, 1, alpha]) # Purple p6_level_5 = np.array([0.25, 0, 0.25, alpha]) # Dark Purple #Palette (7) The Blues: p7_level_1 = np.array([0.8, 0.8, 1, alpha]) # White Blue p7_level_2 = np.array([0.6, 0.6, 1, alpha]) # Clear Blue p7_level_3 = np.array([0.4, 0.4, 1, alpha]) # Pale Blue p7_level_4 = np.array([0, 0, 1, alpha]) # Blue p7_level_5 = np.array([0, 0, 0.25, alpha]) # Dark Blue #Palette (8) The Greyscale: p8_level_1 = np.array([1, 1, 1, alpha]) # White p8_level_2 = np.array([0.8, 0.8, 0.8, alpha]) # Clear Grey p8_level_3 = np.array([0.6, 0.6, 0.6, alpha]) # Pale Grey p8_level_4 = np.array([0.4, 0.4, 0.4, alpha]) # Grey p8_level_5 = np.array([0, 0, 0, alpha]) # Black #Colors used mapping = np.linspace(datac.min(), datac.max(), 256) newcolors = np.empty((256, 4)) newcolors[mapping > 16.5] = p4_level_5 newcolors[mapping < 16.5] = p4_level_3 newcolors[mapping < 11] = p4_level_2 newcolors[mapping < 5.5] = p1_level_1 newcolors[mapping < -5.5] = p1_level_2 newcolors[mapping < -11] = p1_level_3 newcolors[mapping < -16.5] = p1_level_5 my_colormap = ListedColormap(newcolors) if twopanels: p = MyPlotter(shape=(1, 2)) else: p = MyPlotter() p.subplot(0, 0) p.add_points(point_cloud, render_points_as_spheres=True, cmap=my_colormap) if twopanels: p.subplot(0, 1) else: p.subplot(0, 0) # spheres = [] cylinders = [] if molecule: for at in geom.atoms: mesh_sphere = pv.Sphere(radius=0.5, center=[at['x'], at['y'], at['z']]) if at['label'] == 'C': color = [0.4, 0.4, 0.4] elif at['label'] == 'H': color = [0.9, 0.9, 0.9] else: color = [1.0, 0.0, 0.0] spheres.append(mesh_sphere) molecularGraph = graph_theory.detect_cycle.MolecularGraph( "geom.xyz") for e in molecularGraph.getEdges(): idx1 = int(lbl1.replace('a', '')) - 1 idx2 = int(lbl2.replace('a', '')) - 1 at1 = geom.getAtom(idx1) at2 = geom.getAtom(idx2) pos1 = np.asarray([at1['x'], at1['y'], at1['z']]) pos2 = np.asarray([at2['x'], at2['y'], at2['z']]) vect_bond = pos2 - pos1 middle_bond = 0.5 * (pos1 + pos2) mesh_cylinder = pv.Cylinder(center=middle_bond, direction=vect_bond, radius=.2, height=np.linalg.norm(vect_bond)) cylinders.append(mesh_cylinder) # for sphere in spheres: p.add_mesh(sphere, color="tan", show_edges=False) for cyl in cylinders: p.add_mesh(cyl, color="tan", show_edges=False) p.link_views() if shot: p.show(screenshot='airplane.png') else: p.show()