pyvista / pyvista-support Goto Github PK
View Code? Open in Web Editor NEW[moved] Please head over to the Discussions tab of the PyVista repository
Home Page: https://github.com/pyvista/pyvista/discussions
[moved] Please head over to the Discussions tab of the PyVista repository
Home Page: https://github.com/pyvista/pyvista/discussions
I put up an example on repeating textures in the docs but it isn't a good implementation.
If you zoom in, the texture gets mapped funkily where the repetitions should intersect:
Could someone help with correcting this example?
I was wondering if it was possible to select elements on a plot interactively (ex.: a collection of holes) and save them as their own vtk file or perhaps print their table data?
Thank you!
We should add some more tags to make finding issues easier. What else should be included?
Perhaps a tag for each mesh type so that what if you are looking for examples specific to PolyData
you go go to the PolyData
tag (etc. for other mesh types)
Anything else?
Originally post on Slack by user Andrew Annex
hey all, checking out vtki to replace vispy code I have laying around, ran into a texture issue, I have a DEM as a numpy array and an grayscale image overlay I want on the texture but there is some sort of rotation or scaling issue that I can’t seem to solve by using np.rot90, I will post screen shots in just a sec
dem no texture
with texture, looks like from this view it needs to be rotated 180 degrees and not repeat
I am using the texture map function…
dem, img # load from npy files
x = np.arange(0, dem.shape[0])
y = np.arange(0, dem.shape[1])
mx, my = np.meshgrid(x,y, indexing='ij')
grid = vtki.StructuredGrid(mx,my,dem)
grid.texture_map_to_plane(inplace=True)
img = data['img'] * 255
img = np.dstack((img,img,img)).astype(np.uint8)
print(dem.shape, img.shape, img.min(), img.max(), img.dtype,)
texture = vtki.numpy_to_texture(img.transpose((1,0,2)))
grid.plot(texture=texture, cmap='gray')
okay that should be it… I am also running into some silly issue with the gray scale as I moved away from using the matplotlib/cmap code, it is probably just a nan issue
Hello, I am trying to figure out if we can focus on one mesh when plotting multiple meshes. I would like the camera to focus on that mesh more, for example if one mesh is really small, then I would like to zoom in to that to see the details on it.
Dear all,
I have two requests, referring to the case of temperature and power distribution on cylinders meshes, that I'm working on.
Is there a way to divide axially a volume, in order to compute total and average variables over this smaller volumes obtained? For example, I want to divide axially a cylinder volume in smaller volumes, in order to get the power for each of these domains, in addition to the calculation of average power density for each one.
Indeed, I get analogue results for slices, but I get total and average values (compute_cell_sizes function) over surfaces at different height. My intention is to get volumes/domains from intervals between "slices" and carry out the same job for volumes, not surfaces.
Is there a way to get a variable distribution with a "plot over line", like in paraview? In my case, I want to get the centerline temperature along the axial direction. I tried with interpolate function without success. Here I post my test script:
mesh_cyl=pyvista.read("nameFile")
mesh_cyl.set_active_scalar('T')
bottom_pos=[0, 0, 0]
top_pos=[0, 0, 60]
ray=pyvista.Line(bottom_pos, top_pos) #line for centerline
p = pyvista.Plotter()
p.add_mesh(ray, color='blue', line_width=0.000001, label='Ray Segment')
p.add_mesh(mesh_cyl)
interpolated = mesh_cyl.interpolate(ray)
centerLine_T=interpolated.get_scalar('T')
Any suggestions, please?
Thank you for your time.
Regards,
Christian
Say I have several line segments and each one has a name (string), how can I query them and display.
Thanks!
Hello, i am having problems with the color map of my surface, especifically, i can't make it work with a specific sets of data, so the data is wrong? maybe, but the thing is , it work with matplotlib plot_surface.
Here is the pickle file with the data: probando.zip and these images were produced with this code:
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pyvista as pv
import numpy as np
import pickle
# Data from my app
with open('probando.pkl', 'rb') as f:
x, y, z = pickle.load(f)
print(type(z))
print(np.shape(z))
# Matplotlib -----
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(projection='3d')
surface = ax1.plot_surface(x, y, z, cmap='viridis')
fig1.colorbar(surface)
plt.show()
# PyVista -----
grid = pv.StructuredGrid(x, y, z)
plotter = pv.Plotter()
plotter.add_mesh(grid, scalars=z, cmap='viridis', lighting=False)
plotter.set_scale(xscale=(np.max(z)/np.max(x)),
yscale=(np.max(z)/np.max(y)))
plotter.add_scalar_bar()
plotter.show_bounds(grid='back',
location='outer',
ticks='both',
bounds=[np.min(x), np.max(x),
np.min(y), np.max(y),
np.min(z), np.max(z)])
plotter.show()
To make sure it is indeed the data i also compared a generic surface and it work correctly.
code:
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pyvista as pv
import numpy as np
# Known data
x_samp = np.linspace(-10, 10, 20)
y_samp = np.linspace(-10, 10, 20)
x, y = np.meshgrid(x_samp, y_samp)
a = -0.0001
z = a*(np.abs(np.sin(x)*np.sin(y)*np.exp(np.abs(100-np.sqrt(x**2 + y**2)/np.pi))) + 1)**0.1
print(type(z))
print(np.shape(z))
# Matplotlib -----
fig2 = plt.figure(2)
ax2 = fig2.add_subplot(projection='3d')
surface = ax2.plot_surface(x, y, z, cmap='viridis')
fig2.colorbar(surface)
plt.show()
# PyVista -----
grid = pv.StructuredGrid(x, y, z)
plotter = pv.Plotter()
plotter.add_mesh(grid, scalars=z, cmap='viridis', lighting=False)
plotter.set_scale(xscale=(np.max(z)/np.max(x)),
yscale=(np.max(z)/np.max(y)))
plotter.add_scalar_bar()
plotter.show_bounds(grid='back',
location='outer',
ticks='both',
bounds=[np.min(x), np.max(x),
np.min(y), np.max(y),
np.min(z), np.max(z)])
plotter.show()
Any idea what could be happening?
System Information:
Date: Sun Aug 11 20:12:26 2019 Hora est�ndar de Venezuela
Windows : OS
2 : CPU(s)
AMD64 : Machine
32bit : Architecture
Python : Environment
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit
(Intel)]
0.21.4 : pyvista
8.2.0 : vtk
1.17.0 : numpy
2.5.0 : imageio
1.4.3 : appdirs
0.4.3 : scooby
3.1.1 : matplotlib
We need to write guidelines of expected conduct/behavior for this repository
Using pyvista.lines_from_points I create polylines, although each cell contains lines for each connection to point. Is there a way to make it so that it recognizes the entire polyline as a cell?
How can I solve this? Thanks!
def create_line(lines):
lines_frame = {}
poly_array =lines[['Name','x', 'y', 'z']]
n_dh = poly_array['lines'].nunique()
n_rows = len(poly_array)
for i in range (0,n_dh):
lines_frame['poly_array{}'.format(i)] = poly_array[poly_array['Name'] == i]
for i in range (0,n_dh):
lines_frame['coords{}'.format(i)] = (lines_frame['poly_array{}'.format(i)])[['x', 'y', 'z']].values
for i in range (0,n_dh):
for j in range (0,n_rows):
if (poly_array['Name'] == i) is True:
lines_frame['coords{}'.format(i)] = np.append(lines_frame['coords{}'.format(i)],poly_array[poly_array['Name'] == i])
else:
continue
return drillhole_frame
def poly_line(lines):
lines_frame= create_line(lines)
poly_array = lines[['Name','x', 'y', 'z']]
n_dh = poly_array['Name'].nunique()
for i in range (0,n_dh):
lines_frame['poly_segments{}'.format(i)] = lines_from_points(lines_frame['coords{}'.format(i)])
return line_frame
Hi!
I am only starting to use this awesome library, but I was wondering if it is possible to plot isosurfaces (as well as other basic types of plots) on a sphere where (X, Y, Z) directions are not relative to the scene, but rather to the surface of the sphere (as in longitude, latitude, height).
Thanks in advance.
My input data could be in this form:
import numpy as np
# coordinate arrays
lons = np.arange(-180, 181, 2.5)
lats = np.arange(-90, 91, 2)
pressure_levels = np.array([1000, 950, 900, 850, 800, 700, 600, 500])
# the data array
arr = np.random.rand(*(pressure_levels.shape + lats.shape + lons.shape))
# selected isosurfaces
iso_to_plot = [0.2, 0.5]
I am trying to take my point cloud data and convert to a surface mesh. My current approach is using a delaunay 3d filter but that creates sharp edges in the data which won't smooth well.
import pandas
import pyvista
import pymeshfix
coordinates = pandas.read_csv("block.csv")
coordinates = vtk_blocks[['Points:0','Points:1','Points:2']].values
vtk_blocks = pyvista.PolyData(coordinates)
shell = vtk_blocks.delaunay_3d(alpha=17).extract_geometry().clean()
shell = shell.extract_geometry().tri_filter()
shell = shell.split_bodies()
decimated_shell = pv.MultiBlock()
for block in shell:
block = pymeshfix.MeshFix(block.extract_geometry())
block.repair()
block = block.mesh
block = block.extract_geometry().smooth(n_iter=180)
decimated_shell.append(block)
From @tomtomatron:
Anyone have tips for efficiently plotting a large colored point cloud (each point having it's own RGB value in a tuple or array) using pyvista?
Trying to visualize something like this but with points and not a mesh: https://sketchfab.com/3d-models/briery-gap-k1-n-0c81186d72f54a398e85c1f492da625a
Should we create a discourse forum to archive general use questions for PyVista?
I'm imagining something similar to VTK's: https://discourse.vtk.org
This would create a way to archive user questions and provide a place for new users to seek out community based help.
The slack channel has been filling this role, but it's not capable of being a support forum where questions can be searched
I am working with the Multi-Window plotting and am wondering if it is possible to do a couple of things:
set_scale
, show_grid
, etc... applies to all windows (rather than having to define within each subplot).
'Link' the camera between all windows so that zoom/pane applies to all windows simultaneously (when notebook=False)
Thanks!
JG
From @bsburnham:
I'm curious.. with the
slice
tool, could one slice along any orientation, then rotate around the Z vector and choose a "degree" of rotation?
I don't want to look deep into VTK but just simply using your vtkInterface to get the information for a cell or point, getting the index for nearby points.
For example, i can use grid.cell_arrays
or grid.point_array
together with grid.points
to get a dict
of all the "nearly useful" information. But I want to obtain the nearest neighbour for a given point, which enables much flexibility in postprocessing the vtk formatted data. Is it possible using the existing method in vtk? I am asking because I find something like GetCellNeighbors
but since it requires going deep into vtk so I cound't do it on my own.
Alternatively, I know I can using another package such as kdTree
to search for k-nearest neighour
on my own but just curious if there is something already there.
By the way, I think using the kdTree
would enable much more flexibility since if I want to compute a very high order finite difference, I need a large stencil which I think GetCellNeighbors
won't give me but selecting a large enough k, k-nearest neighour
might give me. I don't know if it is something also your interests.
Oh, I think if one can get neighour then one can easily use that to recursively get k-nearest neighour
without using another package such as kdTree, since kdTree requires some sort of computational time.
Greetings! I had a difficulty with trying to find a way to set ranges for a scalar for a 3-D object. For example for a 3D grid the z values would be the scalar and if my minimum and maximum values are 2000 to 10,000, can I make lets say, 2000-4000 red in color, 4000-5000 a green in color and etc...?
As far as I know, I know that you can change the color map pretty easily by using plotter.addmesh(cmap = 'color'), and you can set the overall range also pretty easily by using the plotter.update_scalar_bar_range(clim=[0,10000]).
Could you guys have any feedback on this? Thank you!
I would like to plot a point dataset over a surface. I use this code:
p = pv.Plotter(notebook=False)
p.add_mesh(grav, point_size=10.0, render_points_as_spheres=True, cmap='bwr',scalar_bar_args=sargs, clim=[-50,110],stitle='Residuals')
p.add_mesh(surf, cmap='gray')
p.show()
and I obtain this:
Now I would like to add a vertical exageration factor of 3 to both surface and point set by using the warp_by_scalar
method:
grav = grav.warp_by_scalar(scale_factor=3.0)
surf = surf.warp_by_scalar(scale_factor=3.0)
the resulting plot is:
It seems that the points set has not been scaled correctly. How to fix that?
In the examples I noticed the surfaces use flat shading by default and the smooth function I found in the API although it “relaxes” the mesh, it's not exactly what I'm looking for. Do you have any plans to add such a feature?
I would like to represent boreholes as 'tubes' using top/bottom elevation of the samples. See example file.
Basically, the tube would connect Easting,Northing,Elevation.top to Easting,Northing,Elevation.bot and the color would be based on the 'Geol' field.
Also, could you please provide an example of how you would represent the 'Geol' field as categories? Similar to the functionality in ParaView. Would also appreciate an example of manually defining the color for each category, and the color legend displaying the 'Geol' string (rather than integers).
I am trying to plot a polyline rather than simply plotting the points. I was able to plot a spline but this is not what I want. How can I accomplish this?
This is what I have written so far:
xyz = pd.read_csv('line_points.csv')
coords = xyz[['x', 'y', 'z']].values
poly = pv.PolyData(coords)
spline = pv.Spline(coords)
poly.plot(show_grid=False, point_size=3, color='red')
spline.plot(show_grid=False, point_size=3, color='white')
Every time I run plot something with Plotter, the first time it opens fine, but any other time it closes automatically without fail.
I am plotting lines using the lines_from_points function and then exporting them as .vtk by creating a multiblock, but before doing so, the pandas data frame includes a column for names (ID) for each line. How can I attach these names to each cell for there respective ID's before I export?
Code:
def To_array(row):
"""Convert pandas data frame to numpy array
"""
return np.array([(row['x'],row['y'],row['z']),
(row['x2'],row['y2'],row['z2'])])
def lines_from_points(points):
"""Given an array of points, make a line set"""
poly = pv.PolyData()
poly.points = points
cells = np.full((len(points)-1, 3), 2, dtype=np.int)
cells[:, 1] = np.arange(0, len(points)-1, dtype=np.int)
cells[:, 2] = np.arange(1, len(points), dtype=np.int)
poly.lines = cells
return poly
def save_vtk(segs,location):
blocks = pv.MultiBlock(segs)
merged = blocks.combine()
merged # this is now a single unstructured grid containing all geometry
merged.save(location)
segments = lines.apply(To_array, axis=1)
segs = {}
plotter = pv.Plotter(notebook = False)
for i in range(0, len(segments)):
segs['seg{}'.format(i)] = lines_from_points(segments[i])
plotter.add_mesh(segs['seg{}'.format(i)])
save_vtk(segs,'lines.vtk')
I have a very high resolution surface mesh created from a large scale lidar scan which I'd like to decimate to make dealing with easier. Right now, the mesh has 180748027
cells and 180989696
nodes. 180 million points/cells isn't a dataset larger than what I'm used to dealing with, however it is eating up resources when trying to render/process so I'd like to decimate it to something that can render much faster.
I currently have ~81 separate meshes of StructuredGrid
s in a MultiBlock
dataset which renders a lot faster than a single, merged UnstructuredGrid
, but I really I'd like one, lower-resolution PolyData
object that can render easily along side other datasets.
I'm struggling to figure out how to decimate this large of a dataset - I merged all 81 grids into a single UnstructuredGrid
and tried to run both decimate
and decimate_pro
which I let run for about an hour before killing the process. I've also tried to load and decimate each patch individually but the decimation filters again get hung and take a long time even on just a single patch which almost all them have 2253001
cells and 2256004
.
So I have one MultiBlock
dataset contains 81 StructuredGrid
meshes each with about 2253001
cells and 2256004
points. I'd like to decimate/reduce all of these meshes and combine them to one single triangulated PolyData
mesh which can be loaded/rendered really easily so that I can display it next to many other datasets for this scene. However, I don't want this to take hours to run...
The dataset is ~1.3 GB so I cannot upload it here, but I could share it via Google Drive per request with this code to read it all into a MultiBlock
dataset:
import pyvista as pv
import xarray as xr
import numpy as np
import glob
import os
# DO NOT USE PANEL WITH THIS BIG OF DATA
pv.rcParams['use_panel'] = False
def read_lidar_img(filename):
"""Read lidar point cloud from `.img` file to a single mesh
Helpful: http://xarray.pydata.org/en/stable/auto_gallery/plot_rasterio.html
"""
# Read in the data
data = xr.open_rasterio(filename)
values = np.asarray(data)
nans = values == data.nodatavals
if np.any(nans):
# values = np.ma.masked_where(nans, values)
values[nans] = np.nan
# Make a mesh
xx, yy = np.meshgrid(data['x'], data['y'])
zz = values.reshape(xx.shape)
# zz = np.zeros_like(xx)
mesh = pv.StructuredGrid(xx, yy, zz)
mesh['lidar'] = values.ravel(order='F')
return mesh
files = glob.glob(os.path.join('./2017DTM_lidar_GP_MSH_SpiritLake/', '*.img'))
print('Number of files {}'.format(len(files)))
all_surfaces = pv.MultiBlock()
for i,f in enumerate(files):
name = os.path.basename(f).replace('.img', '')
print('{}/{}: {}'.format(i, len(files), name), end='\r')
surface = read_lidar_img(f)
all_surfaces[-1, name] = surface
print('Done.')
all_surfaces.plot(notebook=False, multi_colors=True, eye_dome_lighting=True)
I have data called shortest distance with is the shortest distance from a list of point to line segments or polylines. I would like to have closer distances (minimum) to be a warm color and the furthest a cold color. I've somewhat been able to accomplish this by setting shortest distance as a scalar and applying a threshold although the color scheme is backward. Is there any way I can accomplish this statically in a plotter?
Here's what I have written so far:
points_array = points[['x', 'y', 'z']].values
poly = pv.PolyData(points_array)
poly['shortest distance'] = points['shortest distance'].values
poly = pv.Threshold(bpoly)
I would like to accomplish the same thing (color by distance) but using plotter:
p = pv.Plotter()
p.add_mesh(bpoly.clip(normal='z',
origin = [0,0,clip_pts]),
color='b', render_points_as_spheres=True)
p.plot()
not much more to said, i want to embed a 3D surface plot in a PySide2 GUI, it is compatible? how?
regards
I have points and lined that are viewed together on a plot using pyvista.plotter and adding a mesh. I am having difficulty
Code:
p = pv.Plotter(notebook=False)
p.add_mesh(points,color='blue',render_points_as_spheres=all)
for i in range(0, len(DH)):
p.add_mesh(globals()['segment{}'.format(i)],color='white',)
p.view_yz()
p.show_axes()
clipper = pv.Clip(p,plotter=p)
I'm trying to add a geotiff (a topo map) to an unstructured grid of the topography DEM.
topo = pv.read(topo_file.vtk)
topo_warp = topo.warp_by_scalar()
topo_clip = topo_warp.clip_box(bounds=clipbox, invert=False)
topo_map = pv.read_texture(topo_map.tif)
p = pv.BackgroundPlotter()
p.add_mesh(topo_clip, name='topo_surface', cmap='gist_gray',
opacity=0.3, texture=topo_map)
However it produces this error. I've clipped the topo_map geotiff to the same extent as the topo dem.
AssertionError: Input mesh does not have texture coordinates to support the texture.
topo_map
(vtkRenderingOpenGL2Python.vtkOpenGLTexture)0000018E1D9C3DC8
I also tried adding texture_map_to_plane
to the topo_clip
topo_clip.texture_map_to_plane(inplace=True)
which worked but the geotiff was incorrectly scaled to the underlying topography surface.
Can you advise the proper way to add a geotiff to an unstructured grid such as a DEM?
I would like to know how to extract point data for polydata on a per cell basis. Ideally this would be in a format of a nx3x3 numpy array, where n is the number of triangles in a trianglular mesh and the x,y,z coordinates of each vertex are given in each row of the 3x3 matrix. However just being able to get an array of the points for each cell would be enough as I could combine and reshape this afterwards.
My reason for doing this is to input these points into another program (which requires this format) after using pyvista to manipulate the original STL import.
I feel like this is probably quite an easy thing to do but so far have been unable to figure out how. I appologise if this has been covered somewhere before but I have searched for some time and cannot find examples of getting the triangle point data, only the mesh point data by using mesh.points.
To create a similar situation using pyvista example files, I have found an example @banesullivan posted on a discourse question.
import vtk
import pyvista as pv
from pyvista import examples
# get some poly data object - use PyVista eample with cell data present
poly_data = examples.download_doorman()
# Make some implicit function to clip with:
plane = vtk.vtkPlane()
plane.SetNormal([1,0,0])
plane.SetOrigin(poly_data.GetCenter())
alg = vtk.vtkClipPolyData()
alg.SetInputDataObject(poly_data)
alg.SetClipFunction(plane) # the the cutter to use the plane we made
alg.SetInsideOut(False) # invert the clip if needed
alg.Update() # Perfrom the Cut
clipped = alg.GetOutput()
# Plot it up... use PyVista because it's easy
pv.plot(clipped)
I would then need to extract the point data for each triangle in clipped as described at the start of the issue.
I would like to voxelize non-uniformly gridded points. This is the code I have written so far:
vtkpoints = PVGeo.points_to_poly_data(unregular_blocks)
voxelizer = PVGeo.filters.VoxelizePoints()
p = pv.Plotter(notebook = False)
grid = voxelizer.apply(vtkpoints)
p.add_mesh(grid)
p.show_axes()
p.plot()
How would I go about doing this?
This is the error I am receiving:
ERROR: In C:\VPP\standalone-build\VTK-source\Filters\Python\vtkPythonAlgorithm.cxx, line 191
vtkPythonAlgorithm (0000026171FAEB30): Failure when calling method: "ProcessRequest":
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\vtk\util\vtkAlgorithm.py", line 151, in ProcessRequest
return vtkself.ProcessRequest(request, inInfo, outInfo)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\vtk\util\vtkAlgorithm.py", line 197, in ProcessRequest
return self.RequestData(request, inInfo, outInfo)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\PVGeo\filters\voxelize.py", line 204, in RequestData
self.__dx, self.__dy, self.__dz, grid=pdo)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\PVGeo\filters\voxelize.py", line 110, in points_to_grid
x,y,z = self.estimate_uniform_spacing(xo, yo, zo)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\PVGeo\filters\voxelize.py", line 88, in estimate_uniform_spacing
xr, yr, zr, dx, dy, angle = r.estimate_and_rotate(x, y, z)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\PVGeo\filters\xyz.py", line 572, in estimate_and_rotate
angle, dx, dy = self._estimate_angle_and_spacing(pts)
File "C:\Users\User\AppData\Local\Continuum\anaconda3\lib\site-packages\PVGeo\filters\xyz.py", line 533, in _estimate_angle_and_spacing
distall, ptsiall = tree.query(pts, k=2)
File "sklearn\neighbors\binary_tree.pxi", line 1309, in sklearn.neighbors.kd_tree.BinaryTree.query
ValueError: k must be less than or equal to the number of training points
I have some surface meshes (PolyData
and/or UnstructuredGrid
s) that have a discontinuities that I'd like to repair. PyMeshFix is generally great for repairing holes in meshes, but how would we approach repairing meshes that are separated like the fillowing screenshot from #17 where a region of the mesh is separated by a sliver:
The data in the screenshot above is difficult to share so, let's see if we can repair the mesh in this example:
import pyvista as pv
from pyvista import examples
import pymeshfix
def generate_split_mesh():
"""Creates an example split mesh for repair"""
mesh = examples.download_st_helens().warp_by_scalar()
xrng = mesh.points[:,0].ptp()
yrng = mesh.points[:,1].ptp()
# region a
bounds = mesh.bounds
bounds[0] += xrng / 3.
bounds[1] -= xrng / 1.55
bounds[3] -= yrng / 2.
# region a
bounds1 = mesh.bounds
bounds1[1] -= xrng / 1.55
bounds1[2] += yrng / 2.
bounds1[3] -= yrng / 2.05
# remove regions
reduced = mesh.extract_geometry().tri_filter().decimate(0.95)
split = reduced.clip_box(bounds, invert=True).clip_box(bounds1, invert=True)
# Make it a triangular mesh
return split.extract_geometry().tri_filter().elevation()
surf = generate_split_mesh()
surf.plot(cpos='xy', show_edges=False)
I tried using PyMeshFix to repair/join the meshes, but this snippet crashes my kernel with this mesh:
fixer = pymeshfix.MeshFix(surf)
fixer.repair(joincomp=True, remove_smallest_components=False)
Then I tired the delaunay_2d
(which applies to the best fitting plane) which worked great for this example:
surf.delaunay_2d().plot(cpos='xy')
However, it did not work for the data in #17 - so maybe there is another way to join split meshes like this?
Also, here's another more complicated example of a split mesh:
import pyvista as pv
from pyvista import examples
import pymeshfix
cow = examples.download_cow()
# Split the cow and cast to PolyData
split_cow = cow.clip_box([-0.2,0.2,-4,3, -2, 2]).extract_geometry()
cpos= [(6.56, 8.73, 22.03),
(0.77, -0.44, 0.0),
(-0.13, 0.93, -0.35)]
split_cow.plot(cpos=cpos, use_panel=False)
fixer = pymeshfix.MeshFix(split_cow)
fixer.repair(joincomp=True, remove_smallest_components=False)
fixer.mesh.plot(cpos=cpos)
Considering that PyMeshFix could handle the more complicated enclosed surface mesh, it should be able to handle a topography surface?
I'm a bit stuck on how to view a 2D image in a 3D scene. The 2D image is a conductivity model inverted from airborne EM data, collected along a flight line.
I have an array of x, y, z and data points. The x coordinates are not constant, but broadly similar (the flight lines are north-south). The y coordinates are not at a constant spacing, but roughly so. The z coordinates have a similar spacing, but a different starting point, as the elevation changes from north to south. There are the same number of z coordinates for each set of x, y coordinates.
Example code:
import pyvista as pv
import numpy as np
import pandas as pd
df = pd.read_csv("example_flightline.csv")
array = df.sort_values(["elev", "northing", "easting"]).values
ny = len(df.northing.unique())
nz = len(df[(df.easting == soundings.easting[0]) & (df.northing == soundings.northing[0])])
mesh = pv.StructuredGrid()
mesh.points = array[:, :3]
mesh.dimensions = [232, 30, 1]
Full example notebook here: https://github.com/kinverarity1/paraview-2d-viz/blob/master/trying%20to%20create%20structuredgrid.ipynb
Originally posted by @lperozzi in OpenGeoVis/omfvista#7
I would like to get a surface from a point set into an OMF object. I set np.nan
value of points a would like to greyed out. The resulting surface is something like this
When I set an out of range value as -9999
to my value the resulting image is:
I would like to have the first image with plein color where the value is not np.nan
. Any idea?
Here is the point set
mod_base_quaternary_300_nan.txt.zip
import pyvista as pv
import pandas as pd
import bumpy as np
import omf
import omfvista
base_quaternary = pd.read_csv('mod_base_quaternary_300.txt')
# simply pass the numpy points to the PolyData constructor
cloud = pv.PolyData(base_quaternary.values)
# Make a surface using the delaunay filter
surf = cloud.delaunay_2d()
tris = surf.faces.reshape(surf.n_cells, 4)[:, 1:4]
base_quaternary = omf.SurfaceElement(
name='My Surface',
description='This is a decription of "My Surface"',
geometry=omf.SurfaceGeometry(vertices=surf.points,
triangles=tris)
)
base_quaternary.validate()
and then
omfvista.wrap(base_quaternary).plot(show_edges=False, notebook=False)
many thanks for your help!
I'd like to do maths on the active scalar, such as taking the log10.
np.log10(model.active_scalar)
returns a numpy array not a vtk object.
Alternatively can I log transform the colour scale?
I was making scatter matrices of data on a mesh and thought it might be cool to make scatter-matrices for the .streamlines()
filter's results. So here's an example doing just that!
Why isn't this in the docs? Because it uses pandas
.
First, checkout out the streamlines example: https://docs.pyvista.org/examples/01-filter/streamlines.html#blood-vessels
The .streamlines()
filter returns the path that the particles take and the values of the dataset through which they propagated. This allows us to inspect aspects of the particle motion with respect to the input velocity field.
The .streamlines()
filter returns three additional scalar attributes describing the particle motion: 'AngularVelocity'
, 'Rotation'
, and 'Vorticity'
. Let's inspect these three attributes with respect to the velocity field used for particle propagation.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas.plotting import scatter_matrix
import pyvista as pv
from pyvista import examples
mesh = examples.download_blood_vessels().cell_data_to_point_data()
mesh.set_active_scalar("velocity")
streamlines, src = mesh.streamlines(
return_source=True, source_radius=10, source_center=(92.46, 74.37, 135.5)
)
boundary = mesh.decimate_boundary().wireframe()
p = pv.Plotter()
p.add_mesh(streamlines.tube(radius=0.2), ligthing=False)
p.add_mesh(src)
p.add_mesh(boundary, color="grey", opacity=0.25)
p.camera_position = [(10, 9.5, -43), (87.0, 73.5, 123.0), (-0.5, -0.7, 0.5)]
p.show()
df = pd.DataFrame()
# Grab input data
df['vel'] = np.linalg.norm(streamlines['velocity'], axis=1)
# Grab simulation results
df['ang_vel'] = streamlines['AngularVelocity']
df['rot'] = streamlines['Rotation']
df['vort'] = np.linalg.norm(streamlines['Vorticity'], axis=1)
# Generate scatter matrix
scatter_matrix(df, figsize=(10, 10), diagonal='kde')
plt.show()
Is there a method to export meshes or their csv files as a vtk file and not a vtkjs file?
Thanks!
Is there a way to set the voxelizer recovery angle? There is a method for setting the cell sizes, although I have not been able to find a way to do this with the recovery angle.
I have a uniform point grid and I receive the proper deltas and recovery angle when I plot it as a whole. Although, when I try to sort for blocks within a certain range and plot it the angle seems to be different and the cubes overlap when they should not be.
voxelizer_sorted = PVGeo.filters.VoxelizePoints(unique=False, estimate=False) voxelizer_sorted.set_deltas(75,75,75)
what I would like to do:
voxelizer_sorted.set_angle(get_recovered_angle(degrees=False))
I am trying to view my 3d plot in the xy plane as a slice of the 3d model lat a given elevation.
I have been able to add a grid top the plot although it shows a box. How would I go about having the grid only be shown in the 2d plane (not as a box) at the elevation of the clip? Also, can I view the 2D plane as a parallel projection? I know this can be done in paraview so I assume it can also be done in pyvista.
code:
p = pv.Plotter(notebook=False)
p.add_mesh(bpoly, cmap='coolwarm_r',scalars='shortest distance',render_points_as_spheres=True)
for i in range(0, len(DH)):
p.add_mesh(globals()['seg{}'.format(i)],color='yellow')
p.add_mesh(polyLine,color='magenta')
p.view_xy(negative=False)
p.show_axes()
p.show_grid()
p.plot(screenshot='plot.png')
I am trying to plot points as blocks, and the goal is to have them all perfectly in line. I've been able to have the blocks stack perfectly although they would need to be rotated in order to be perfect. How would I go about this?
Code so far:
block_pts = blocks[['x', 'y', 'z']].values
Poly = pv.PolyData(block_pts)
geom = pv.Cube()
cubes = Poly.glyph(geom=geom,scale=False,factor=75,absolute=True)
p = pv.Plotter()
p.add_mesh(cubes)
p.plot()
Is it possible to add multiple sliders/multiples thresholds at once?
In #32, I was shown how to clip several meshes by combining them. I have points and line segments, from there I have a threshold for the closest points to the lines. I also have a clip slider for the elevation.
The goal is to try and have a threshold for the elevation of the point and the line individually and for the shortest distance in one plot. Is this possible?
Hello, I am trying to figure out how I be able to apply X,Y,Z points to create a 3-D surface grid using pyVista? Similar to the quick example, "Creating a Structured Surface" on the website (https://docs.pyvista.org/examples/00-load/create-structured-surface.html#sphx-glr-examples-00-load-create-structured-surface-py). But in my case, I have thousands of X,Y,Z points in space. I am able to do this using matplotlib.pyplot in python however, I cannot seem to work out how to do it using pyVista.
Dear Pyvista Team,
I wanted to ask you how can I colour a isosurface with the values of the axial position.
I have been already able to extract the desired surface as you can see the in the image attached.
The problem is that I want to colour a surface with a certain value as the example in this link:
https://www.researchgate.net/figure/Isosurfaces-of-vorticity-magnitude-coloured-by-axial-position-z-where-the-vorticity_fig1_278646580
I tried using the scalars parameters in several ways or the plot_curvature option with clim, but I am unsuccessful...
Here is my code:
# Create the spatial reference
grid = pv.UniformGrid()
grid.dimensions = np.array(Enstrophy.shape) + 1
grid.origin = (0, 0, 0) # The bottom left corner of the data set
grid.spacing = (1, 1, 1) # These are the cell sizes along each axis
grid.cell_arrays["values"] = Enstrophy.flatten(order="F") # Flatten the array!
nodal = grid.cell_data_to_point_data()
geom = nodal.extract_geometry()
print(geom.number_of_points)
contours = nodal.contour(isosurfaces=5, scalars="axial")
pv.set_plot_theme("document")
contours.plot(cmap='Spectral')
cpos = contours.plot_curvature(curv_type='mean', clim=[0, 10] )
plotter = pv.Plotter() # instantiate the plotter
plotter.add_mesh(contours) # add a dataset to the scene
cpos = plotter.show() # show the rendering window
plotter = pv.Plotter(off_screen=True)
plotter.add_mesh(contours, cmap='Spectral')
plotter.camera_position = cpos
plotter.show(auto_close=False)
plotter.screenshot('vorticity.png')
plotter.close()
Can you point me in the direction I need to work on to achieve this figure?
I really appreciate your time and attention.
Ismael
I have an stl file and would like to get the indices of all the cells visible from a chosen viewpoint. I know this is possible in vtk using the vtkHardwareSelector but am curious if it is possible in pyvista?
In addition I would also like to know if there is an existing fuction for projecting 3D point data onto a plane?
I'd like to be able to clip a mesh by an irregular shaped polygon cylinder. This polygon could be defined by the perimeter of a set of datapoints (ie like observations in a geophysical survey), or it could be defined manually using coordinates of the top and bottom of the cylinder.
I would then use this polygon cylinder surface as input into the dataset.clip_surface()
filter. The intention is to clip a geophysical model (which is a rectangular cube) to the actual data measurement point distribution, which is a random shape.
When I use RGBA colors inside a Jupyter Notebook, I obtain an unexpected result:
import pyvista as pv
import numpy as np
sphere = pv.Sphere()
scalars = np.ones((sphere.GetNumberOfPoints(), 4)) * 255.0
scalars = scalars.astype('ubyte')
p = pv.Plotter()
p.add_mesh(sphere, rgba=True, scalars=scalars)
p.show()
When I run this script natively, I get the right result of course:
Hello everyone, I am quite new to PyVista, I want to plot several 3d curves in a single plot, what would be best way to do it ?
A 3D curve can be seen as a polyline with vertex positions and vertex positions are given as a ndarray (nx3) for a curve with n vertices. I have several ndarrays regarding a set of 3D curves and want to plot them. I like the visual representation of streamlines in PyVista. Can these curve be plotted with similar visuals ?
I am looking forward to your valuable suggestions
For example, I am attaching 3 csv files regarding x, y, and z coordinates of 24 different curves
3dcurves.zip
I would like to be able to append my meshes/combine them before I save them as a .vtk. I have multiple tubes and after I generate them I would prefer to have them all in one vtk file rather than having them all separate.
I have looked into the class pyvista.MultiBlock and append but I have not been able to apply it.
I have the tube data in a dictionary and I would have to loop through in order to add them as arguments combine them.
Thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.