I want to extract some data (e.g. scalars) from a VTK file along with their coordinates on the grid then process it in Matplotlib. The problem is I dont know how to grab the point/cell data from the VTK file (by giving the name of the scalar, for instance) and load them into a numpy array using vtk_to_numpy
My code should look like:
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
import numpy as np
from vtk import *
from vtk.util.numpy_support import vtk_to_numpy
# load input data
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName("my_input_data.vtk")
reader.Update()
(...missing steps)
# VTK to Numpy
my_numpy_array = vtk_to_numpy(...arguments ?)
#Numpy to Matplotlib (after converting my_numpy_array to x,y and z)
CS = plt.contour(x,y,z,NbLevels)
...
PS:I know that Paraview could do the task, but I am trying post process some data without having to open Paraview. Any help is appreciated
Edit 1
I found this pdf tutorial to be very useful to learn the basics of handling VTK files
I finally figured a way (maybe not the optimal) that does the job. The example here is contour plotting a temperature field extracted from a vtk file:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.interpolate import griddata
import numpy as np
import vtk
from vtk.util.numpy_support import vtk_to_numpy
# load a vtk file as input
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName("my_input_data.vtk")
reader.Update()
# Get the coordinates of nodes in the mesh
nodes_vtk_array= reader.GetOutput().GetPoints().GetData()
#The "Temperature" field is the third scalar in my vtk file
temperature_vtk_array = reader.GetOutput().GetPointData().GetArray(3)
#Get the coordinates of the nodes and their temperatures
nodes_nummpy_array = vtk_to_numpy(nodes_vtk_array)
x,y,z= nodes_nummpy_array[:,0] , nodes_nummpy_array[:,1] , nodes_nummpy_array[:,2]
temperature_numpy_array = vtk_to_numpy(temperature_vtk_array)
T = temperature_numpy_array
#Draw contours
npts = 100
xmin, xmax = min(x), max(x)
ymin, ymax = min(y), max(y)
# define grid
xi = np.linspace(xmin, xmax, npts)
yi = np.linspace(ymin, ymax, npts)
# grid the data
Ti = griddata((x, y), T, (xi[None,:], yi[:,None]), method='cubic')
## CONTOUR: draws the boundaries of the isosurfaces
CS = plt.contour(xi,yi,Ti,10,linewidths=3,cmap=cm.jet)
## CONTOUR ANNOTATION: puts a value label
plt.clabel(CS, inline=1,inline_spacing= 3, fontsize=12, colors='k', use_clabeltext=1)
plt.colorbar()
plt.show()
I don't know what's you dataset looks like, so here is only some method that you can get the point locations and scalars values:
from vtk import *
from vtk.util.numpy_support import vtk_to_numpy
# load input data
reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(r"C:\Python27\VTKData\Data\uGridEx.vtk")
reader.Update()
ug = reader.GetOutput()
points = ug.GetPoints()
print vtk_to_numpy(points.GetData())
print vtk_to_numpy(ug.GetPointData().GetScalars())
it will be a little easy if you can use tvtk
:
from tvtk.api import tvtk
reader = tvtk.GenericDataObjectReader()
reader.file_name = r"C:\Python27\VTKData\Data\uGridEx.vtk"
reader.update()
ug = reader.output
print ug.points.data.to_array()
print ug.point_data.scalars.to_array()
if you want to do contour
plot in matplotib, I think you need a grid, you may need use some VTK class to convert the dataset to a grid, such as vtkProbeFilter
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With