Search code examples
pythonarraysnumpymatplotlibvtk

VTK to Matplotlib using Numpy


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


Solution

  • 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() 
    

    enter image description here