def ear_clip_plane(V: np.ndarray, band_id): Ar, Al = V[-2:] CAr, CAl = V[-2:] + V[band_id] direction = np.cross(Al, CAl) return pv.Plane(V[band_id] * .55, direction, np.linalg.norm(Al) * 3.0, np.linalg.norm(V[band_id]) * 1.3)
def draw_tnb_frame(p: pv.Plotter, v, t, n, b, arrow_size=arrow_size): p.add_mesh(pv.Arrow(start=v, direction=t * arrow_size, scale="auto"), color="red") p.add_mesh(pv.Arrow(start=v, direction=n * arrow_size, scale="auto"), color="green") p.add_mesh(pv.Arrow(start=v, direction=b * arrow_size, scale="auto"), color="blue") p.add_mesh(pv.Plane(v, n, arrow_size * 4, arrow_size * 4), color=tangent_plane_color, opacity=0.6)
def test_normals_set(): plane = pyvista.Plane(i_resolution=1, j_resolution=1) plane.point_data.normals = plane.point_normals assert np.array_equal(plane.point_data.active_normals, plane.point_normals) with raises(ValueError, match='must be a 2-dim'): plane.point_data.active_normals = [1] with raises(ValueError, match='must match number of points'): plane.point_data.active_normals = [[1, 1, 1], [0, 0, 0]] with raises(ValueError, match='Normals must have exactly 3 components'): plane.point_data.active_normals = [[1, 1], [0, 0], [0, 0], [0, 0]]
def test_active_vectors_eq(): mesh = pyvista.Plane(i_resolution=1, j_resolution=1) vectors0 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors0, 'vectors0') vectors1 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors1, 'vectors1') other_mesh = mesh.copy(deep=True) assert mesh == other_mesh mesh.point_data.active_vectors_name = 'vectors0' assert mesh != other_mesh
def test_add_two_vectors(): """Ensure we can add two vectors""" mesh = pyvista.Plane(i_resolution=1, j_resolution=1) mesh.point_data.set_array(range(4), 'my-scalars') mesh.point_data.set_array(range(5, 9), 'my-other-scalars') vectors0 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors0, 'vectors0') vectors1 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors1, 'vectors1') assert 'vectors0' in mesh.point_data assert 'vectors1' in mesh.point_data
def fit_plane_to_points(points, return_meta=False): """Fit a plane to a set of points using the SVD algorithm. Parameters ---------- points : sequence Size ``[N x 3]`` sequence of points to fit a plane through. return_meta : bool, optional If ``True``, also returns the center and normal used to generate the plane. Returns ------- pyvista.PolyData Plane mesh. numpy.ndarray Plane center if ``return_meta=True``. numpy.ndarray Plane normal if ``return_meta=True``. Examples -------- Fit a plane to a random point cloud. >>> import pyvista >>> import numpy as np >>> cloud = np.random.random((10, 3)) >>> cloud[:, 2] *= 0.1 >>> plane, center, normal = pyvista.fit_plane_to_points(cloud, return_meta=True) Plot the fitted plane. >>> pl = pyvista.Plotter() >>> _ = pl.add_mesh(plane, color='tan', style='wireframe', line_width=4) >>> _ = pl.add_points(cloud, render_points_as_spheres=True, ... color='r', point_size=30) >>> pl.show() """ data = np.array(points) center = data.mean(axis=0) result = np.linalg.svd(data - center) normal = np.cross(result[2][0], result[2][1]) plane = pyvista.Plane(center=center, direction=normal) if return_meta: return plane, center, normal return plane
def test_active_vectors_name_setter(): mesh = pyvista.Plane(i_resolution=1, j_resolution=1) mesh.point_data.set_array(range(4), 'my-scalars') vectors0 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors0, 'vectors0') vectors1 = np.random.random((4, 3)) mesh.point_data.set_vectors(vectors1, 'vectors1') assert mesh.point_data.active_vectors_name == 'vectors1' mesh.point_data.active_vectors_name = 'vectors0' assert mesh.point_data.active_vectors_name == 'vectors0' with raises(KeyError, match='does not contain'): mesh.point_data.active_vectors_name = 'not a valid key' with raises(ValueError, match='needs 3 components'): mesh.point_data.active_vectors_name = 'my-scalars'
def fit_plane_to_points(points, return_meta=False): """Fit a plane to a set of points. Parameters ---------- points : np.ndarray Size n by 3 array of points to fit a plane through return_meta : bool If true, also returns the center and normal used to generate the plane """ data = np.array(points) center = data.mean(axis=0) result = np.linalg.svd(data - center) normal = np.cross(result[2][0], result[2][1]) plane = pyvista.Plane(center=center, direction=normal) if return_meta: return plane, center, normal return plane
Run a modal analysis on a mesh generated from pyvista within MAPDL. """ # sphinx_gallery_thumbnail_number = 2 import os import pyvista as pv import pyansys # launch MAPDL and run a modal analysis os.environ['I_MPI_SHM_LMT'] = 'shm' # necessary for Ubuntu mapdl = pyansys.launch_mapdl(loglevel='WARNING', override=True) # Create a simple plane mesh centered at (0, 0, 0) on the XY plane mesh = pv.Plane(i_resolution=100, j_resolution=100) mesh.plot(color='w', show_edges=True) ############################################################################### # Write the mesh to an archive file archive_filename = os.path.join(mapdl.path, 'tmp.cdb') pyansys.save_as_archive(archive_filename, mesh) ############################################################################### # mapdl = pyansys.launch_mapdl(prefer_pexpect=True, override=True) # Read in the archive file response = mapdl.cdread('db', archive_filename) mapdl.prep7() print(mapdl.shpp('SUMM'))
wavelengths, dense=False, ray_length=100, angle_type=angle_type) # ============================================================================= # Set up the plot plot = pv.Plotter() plot.add_axes() ray_drawer = drawing.RayDrawer3D(plot) # draw a visual target in the x-y plane, for reference visual_target = pv.Plane(center=(0, 0, 0), direction=(0, 0, 1), i_size=target_x_size, j_size=target_y_size, i_resolution=1, j_resolution=1) plot.add_mesh(visual_target, color="green") # draw a visual backing that the source will slide along, at the proper # rotation and offset visual_backing = pv.Plane(center=(0.0, .99 * source_y_offset, -.99 * target_z_distance), direction=(0.0, -source_y_offset, target_z_distance), i_size=target_y_size, j_size=5 * source_size, i_resolution=1, j_resolution=1) plot.add_mesh(visual_backing, color="green")
def remesh( mesh: pv.PolyData, meridian: float, boundary: Optional[bool] = False, check: Optional[bool] = False, warnings: Optional[bool] = False, ) -> Remesh: """ TODO Notes ----- .. versionadded :: 0.1.0 """ if not warnings: # https://public.kitware.com/pipermail/vtkusers/2004-February/022390.html vtkObject.GlobalWarningDisplayOff() if mesh.n_cells == 0: emsg = "Cannot remesh an empty mesh" raise ValueError(emsg) meridian = wrap(meridian)[0] radius = calculate_radius(mesh) logger.debug( "meridian=%s, radius=%s", meridian, radius, ) poly0: pv.PolyData = mesh.copy(deep=True) if GV_CELL_IDS not in poly0.cell_data: poly0.cell_data[GV_CELL_IDS] = np.arange(poly0.n_cells) if GV_POINT_IDS not in poly0.point_data: poly0.point_data[GV_POINT_IDS] = np.arange(poly0.n_points) if not triangulated(poly0): start = datetime.now() poly0.triangulate(inplace=True) end = datetime.now() logger.debug( "mesh: triangulated [%s secs]", (end - start).total_seconds(), ) poly1 = pv.Plane( center=(radius / 2, 0, 0), i_resolution=1, j_resolution=1, i_size=radius, j_size=radius * 2, direction=(0, 1, 0), ) poly1.rotate_z(meridian, inplace=True) poly1.triangulate(inplace=True) # https://vtk.org/doc/nightly/html/classvtkIntersectionPolyDataFilter.html alg = _vtk.vtkIntersectionPolyDataFilter() alg.SetInputDataObject(0, poly0) alg.SetInputDataObject(1, poly1) # BoundaryPoints (points) mask array alg.SetComputeIntersectionPointArray(True) # BadTriangle and FreeEdge (cells) mask arrays alg.SetCheckMesh(check) alg.SetSplitFirstOutput(True) alg.SetSplitSecondOutput(False) start = datetime.now() alg.Update() end = datetime.now() logger.debug( "remeshed: lines=%s, points=%s [%s secs]", alg.GetNumberOfIntersectionLines(), alg.GetNumberOfIntersectionPoints(), (end - start).total_seconds(), ) remeshed: pv.PolyData = _get_output(alg, oport=1) if not warnings: vtkObject.GlobalWarningDisplayOn() if remeshed.n_cells == 0: # no remeshing has been performed as the meridian does not intersect the mesh remeshed_west, remeshed_east = pv.PolyData(), pv.PolyData() logger.debug( "no remesh performed using meridian=%s", meridian, ) else: # split the triangulated remesh into its two halves, west and east of the meridian centers = remeshed.cell_centers() lons = to_xy0(centers)[:, 0] delta = lons - meridian lower_mask = (delta < 0) & (delta > -180) upper_mask = delta > 180 west_mask = lower_mask | upper_mask east_mask = ~west_mask logger.debug( "split: lower=%s, upper=%s, west=%s, east=%s, total=%s", lower_mask.sum(), upper_mask.sum(), west_mask.sum(), east_mask.sum(), remeshed.n_cells, ) # the vtkIntersectionPolyDataFilter is configured to *always* generate the boundary mask point array # as we require it internally, regardless of whether the caller wants it or not afterwards boundary_mask = np.asarray(remeshed.point_data[VTK_BOUNDARY_MASK], dtype=bool) if not boundary: del remeshed.point_data[VTK_BOUNDARY_MASK] remeshed.point_data[GV_REMESH_POINT_IDS] = remeshed[GV_POINT_IDS].copy( ) remeshed[GV_REMESH_POINT_IDS][boundary_mask] = REMESH_SEAM remeshed_west = cast_UnstructuredGrid_to_PolyData( remeshed.extract_cells(west_mask)) join_mask = np.where( remeshed_west[GV_REMESH_POINT_IDS] != REMESH_SEAM)[0] remeshed_west[GV_REMESH_POINT_IDS][join_mask] = REMESH_JOIN remeshed[GV_REMESH_POINT_IDS][boundary_mask] = REMESH_SEAM_EAST remeshed_east = cast_UnstructuredGrid_to_PolyData( remeshed.extract_cells(east_mask)) join_mask = np.where( remeshed_east[GV_REMESH_POINT_IDS] != REMESH_SEAM_EAST)[0] remeshed_east[GV_REMESH_POINT_IDS][join_mask] = REMESH_JOIN del remeshed.point_data[GV_REMESH_POINT_IDS] sanitize_data(remeshed, remeshed_west, remeshed_east) return remeshed, remeshed_west, remeshed_east
lens = boundaries.ParametricMultiTriangleBoundary( zero_points, vg, [ boundaries.ThicknessConstraint(0.0, "min"), boundaries.ThicknessConstraint(0.2, "min"), ], [True, False], auto_update_mesh=True, material_list=[{ "mat_in": 1, "mat_out": 0 }] * 2, vertex_update_map=vertex_update_map) target = boundaries.ManualTriangleBoundary( mesh=pv.Plane(center=(target_distance, 0, 0), direction=(1, 0, 0), i_size=100, j_size=100, i_resolution=1, j_resolution=1).triangulate()) target.frozen = True # build the optical system system = engine.OpticalSystem3D() system.optical = lens.surfaces system.targets = [target] system.sources = [random_source] system.materials = [{"n": materials.vacuum}, {"n": materials.acrylic}] system.update() # draw the boundary plot = pv.Plotter() plot.add_axes()
# Set up the source angular_size = PI / 8 print(f"Angular Size: {np.degrees(angular_size)}") #sphere = dist.StaticUniformSphere(angular_size, 100000) #sphere = dist.RandomUniformSphere(angular_size, 100000) #sphere = dist.StaticLambertianSphere(angular_size, 100000) sphere = dist.RandomLambertianSphere(angular_size, 100000) source = sources.PointSource(3, (0, 0, 0), (1, 0, 0), sphere, [drawing.YELLOW]) source.frozen = True print(f"Minimum phi generated: {np.degrees(tf.reduce_min(sphere.ranks[:,0]))}") print(f"Maximum phi generated: {np.degrees(tf.reduce_max(sphere.ranks[:,0]))}") # Set up the target angular_step_size = 5 plane_mesh = pv.Plane((1, 0, 0), (1, 0, 0), i_size=.1, j_size=.1).triangulate() target = boundaries.ManualTriangleBoundary(mesh=plane_mesh) # set up the system system = engine.OpticalSystem3D() system.sources = [source] system.targets = [target] eng = engine.OpticalEngine(3, [], optical_system=system) def rotate_target(): target.mesh.rotate_y(angular_step_size) if True:
pl.add_mesh(base_mesh) pl.enable_shadows() pl.camera.zoom(1.5) pl.show() ############################################################################### # Show light penetrating several planes. Adjust the light intensity # and the ``shadow_attenuation`` to change how many planes the # light can go through. plotter = pyvista.Plotter(lighting=None, window_size=(800, 800)) # add several planes for plane_y in [2, 5, 10]: screen = pyvista.Plane(center=(0, plane_y, 0), direction=(0, 1, 0), i_size=5, j_size=5) plotter.add_mesh(screen, color='white') light = pyvista.Light(position=(0, 0, 0), focal_point=(0, 1, 0), color='cyan', intensity=15, positional=True, cone_angle=15, attenuation_values=(2, 0, 0)) light.show_actor() plotter.add_light(light) plotter.view_vector((1, -2, 2)) plotter.enable_shadows()
def test_set_viewup(): plane = pyvista.Plane() p = pyvista.Plotter() p.add_mesh(plane, color="tan", show_edges=True) p.set_viewup((1.0, 1.0, 1.0)) p.show(before_close_callback=verify_cache_image)
""" # sphinx_gallery_thumbnail_number = 3 import pyvista as pv ############################################################################### plotter = pv.Plotter() actor = plotter.add_mesh(pv.Sphere()) plotter.remove_actor(actor) plotter.show() ############################################################################### # Clearing the entire plotting window: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere()) plotter.add_mesh(pv.Plane()) plotter.clear() # clears all actors plotter.show() ############################################################################### # Or you can give any actor a ``name`` when adding it and if an actor is added # with that same name at a later time, it will replace the previous actor: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere(), name="mydata") plotter.add_mesh(pv.Plane(), name="mydata") # Only the Plane is shown! plotter.show()
def test_plane(): surf = pyvista.Plane() assert np.any(surf.points) assert np.any(surf.faces)
# Compute center of mass femur_cm = compute_center_of_mass(femur.points) # Compute bounding box of femur box_bb = bounding_box_3d(femur.points) # Shaft axis shaft_axis = np.array([0, 0, 1]) if (DISPLAY): # Show shaft line lines = np.hstack(([femur_cm[0], femur_cm[1], femur_cm[2]-100], [femur_cm[0], femur_cm[1], femur_cm[2]+100])) p.add_lines(lines) # Othogonal planes axial_plane = pv.Plane( femur_cm, direction=shaft_axis, i_size=150, j_size=150) sagitall_plane = pv.Plane(femur_cm, direction=np.array( [1, 0, 0]), i_size=150, j_size=150) if (DISPLAY): p.add_mesh(axial_plane, color='white', opacity=0.2, label='Axial Plane') p.add_mesh(sagitall_plane, color='white', opacity=0.2, label='Sagittal Plane') # Initial AnteriorPosterior direction initial_antero_posterior_axis = np.array([0, 1, 0]) # Initial frontal plane initial_antero_posterior_plane = pv.Plane(femur_cm, direction=initial_antero_posterior_axis, i_size=150, j_size=150)
surface1 = boundaries.ManualTriangleBoundary( file_name="./stl/short_pyramid.stl", material_dict={ "mat_in": 1, "mat_out": 0 }) surface2 = boundaries.ManualTriangleBoundary(mesh=pv.Sphere(radius=.5, center=(1, 0, 0)), material_dict={ "mat_in": 1, "mat_out": 0 }) surface3 = boundaries.ManualTriangleBoundary( mesh=pv.Plane(center=(3, 0, 0), direction=(1, 0, 0), i_size=7, j_size=7, i_resolution=1, j_resolution=1).triangulate()) # build the optical system system = engine.OpticalSystem3D() system.optical = [surface1, surface2] system.targets = [surface3] system.sources = [source] system.materials = [{"n": materials.vacuum}, {"n": materials.acrylic}] system.update() # draw the boundary plot = pv.Plotter() surface1.mesh.rotate_y(-90) surface1.update_from_mesh()
~~~~~~~~~~~~~~~~~ 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) p.add_mesh(cyl, color="tan", show_edges=True) p.subplot(0, 1) p.add_mesh(arrow, color="tan", show_edges=True)
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 get_test_square(angle): plane = pv.Plane((5, np.sin(angle), np.cos(angle)), (0, np.sin(angle), np.cos(angle)), .1, .1, 1, 1).triangulate() return boundaries.ManualTriangleBoundary(mesh=plane)
def test_invalid_overwrite(grid): with pytest.raises(TypeError): grid.overwrite(pyvista.Plane())
""" # sphinx_gallery_thumbnail_number = 3 import pyvista as pv ############################################################################### plotter = pv.Plotter() actor = plotter.add_mesh(pv.Sphere()) plotter.remove_actor(actor) plotter.show() ############################################################################### # Clearing the entire plotting window: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere()) plotter.add_mesh(pv.Plane()) plotter.clear() # clears all actors plotter.show() ############################################################################### # Or you can give any actor a ``name`` when adding it and if an actor is added # with that same name at a later time, it will replace the previous actor: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere(), name="mymesh") plotter.add_mesh(pv.Plane(), name="mymesh") # Only the Plane is shown! plotter.show()
the sense that they are unidirectional lights with a finite position, so they can be visualized using a cone. This is exactly the purpose of a ``vtk.vtkLightActor``, the functionality of which can be enabled for spotlights: """ # sphinx_gallery_thumbnail_number = 1 import numpy as np import pyvista as pv from pyvista import examples cow = examples.download_cow() cow.rotate_x(90) plotter = pv.Plotter(lighting='none', window_size=(1000, 1000)) plotter.add_mesh(cow, color='white') floor = pv.Plane(center=(*cow.center[:2], cow.bounds[-2]), i_size=30, j_size=25) plotter.add_mesh(floor, color='green') UFO = pv.Light(position=(0, 0, 10), focal_point=(0, 0, 0), color='white') UFO.positional = True UFO.cone_angle = 40 UFO.exponent = 10 UFO.intensity = 3 UFO.show_actor() plotter.add_light(UFO) # enable shadows to better demonstrate lighting plotter.enable_shadows() plotter.camera_position = [(28, 30, 22), (0.77, 0, -0.44), (0, 0, 1)] plotter.show()
from the point source. In all cases a larger attenuation value (of a given kind) means stronger dampening (weaker light at a given distance). So the constant attenuation parameter corresponds roughly to a constant intensity component. The linear and the quadratic attenuation parameters correspond to intensity components that decay with distance from the source. For the same parameter value the quadratic attenuation produces a beam that is shorter in range than that produced by linear attenuation. Three spotlights with three different attenuation profiles each: """ # sphinx_gallery_thumbnail_number = 3 import pyvista as pv plotter = pv.Plotter(lighting='none') billboard = pv.Plane(direction=(1, 0, 0), i_size=6, j_size=6) plotter.add_mesh(billboard, color='white') all_attenuation_values = [(1, 0, 0), (0, 2, 0), (0, 0, 2)] offsets = [-2, 0, 2] for attenuation_values, offset in zip(all_attenuation_values, offsets): light = pv.Light(position=(0.1, offset, 2), focal_point=(0.1, offset, 1), color='cyan') light.positional = True light.cone_angle = 20 light.intensity = 15 light.attenuation_values = attenuation_values plotter.add_light(light) plotter.view_yz()
def plane(): return pyvista.Plane()
""" # sphinx_gallery_thumbnail_number = 3 import pyvista as pv ################################################################################ plotter = pv.Plotter() actor = plotter.add_mesh(pv.Sphere()) plotter.remove_actor(actor) plotter.show() ################################################################################ # Clearing the entire plotting window: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere()) plotter.add_mesh(pv.Plane()) plotter.clear() # clears all actors plotter.show() ################################################################################ # Or you can give any actor a ``name`` when adding it and if an actor is added # with that same name at a later time, it will replace the previous actor: plotter = pv.Plotter() plotter.add_mesh(pv.Sphere(), name='mydata') plotter.add_mesh(pv.Plane(), name='mydata') # Only the Plane is shown! plotter.show()