This Plot3 python matplotlib script is useful. But there are times when all I have is a txt or csv file with the xyz data and I just want to see the 3d view. Firing up python IDE , loading the data and using the plot3 script becomes too many steps. And the output 3d plot’s handling leave much to be desired.
So building on VTK docs python examples, have developed this python script to display 3D xyz data from a file.
The simple command is python xyzviewer.py filename
That’s it and you get a VTK window with interactive display of the data. Of course needs VTK installed in python.
Here’s a short 9 sec demo of the 3D display.
And if you are still curious, you can look at the plot3 here.
Update: If the formatting fails you, download vtkpointsdisplay from here.
And here’s the updated code for anyone interested. Thanks Ralv and Samir.
'''
Modified Python 3 VTK script to Display 3D xyz data
'''
import vtk
from numpy import random,genfromtxt,size
class VtkPointCloud:
def __init__(self, zMin=-10.0, zMax=10.0, maxNumPoints=1e6):
self.maxNumPoints = maxNumPoints
self.vtkPolyData = vtk.vtkPolyData()
self.clearPoints()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(self.vtkPolyData)
mapper.SetColorModeToDefault()
mapper.SetScalarRange(zMin, zMax)
mapper.SetScalarVisibility(1)
self.vtkActor = vtk.vtkActor()
self.vtkActor.SetMapper(mapper)
def addPoint(self, point):
if (self.vtkPoints.GetNumberOfPoints() < self.maxNumPoints):
pointId = self.vtkPoints.InsertNextPoint(point[:])
self.vtkDepth.InsertNextValue(point[2])
self.vtkCells.InsertNextCell(1)
self.vtkCells.InsertCellPoint(pointId)
else:
r = random.randint(0, self.maxNumPoints)
self.vtkPoints.SetPoint(r, point[:])
self.vtkCells.Modified()
self.vtkPoints.Modified()
self.vtkDepth.Modified()
def clearPoints(self):
self.vtkPoints = vtk.vtkPoints()
self.vtkCells = vtk.vtkCellArray()
self.vtkDepth = vtk.vtkDoubleArray()
self.vtkDepth.SetName('DepthArray')
self.vtkPolyData.SetPoints(self.vtkPoints)
self.vtkPolyData.SetVerts(self.vtkCells)
self.vtkPolyData.GetPointData().SetScalars(self.vtkDepth)
self.vtkPolyData.GetPointData().SetActiveScalars('DepthArray')
def load_data(filename,pointCloud):
data = genfromtxt(filename,dtype=float,usecols=[0,1,2])
for k in range(size(data,0)):
point = data[k] #20*(random.rand(3)-0.5)
pointCloud.addPoint(point)
return pointCloud
if __name__ == '__main__':
import sys
if (len(sys.argv) < 2):
print ('Usage: xyzviewer.py itemfile')
sys.exit()
pointCloud = VtkPointCloud()
pointCloud=load_data(sys.argv[1],pointCloud)
# Renderer
renderer = vtk.vtkRenderer()
renderer.AddActor(pointCloud.vtkActor)
#renderer.SetBackground(.2, .3, .4)
renderer.SetBackground(0.0, 0.0, 0.0)
renderer.ResetCamera()
# Render Window
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
# Interactor
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
# Begin Interaction
renderWindow.Render()
renderWindow.SetWindowName("XYZ Data Viewer"+sys.argv[1])
renderWindowInteractor.Start()
Hello,
This seem like a very useful code. During execution it complains about syntax in line 25. Any help will be kindly appreciated.
Cheers,
Senu
LikeLike
Thanks Senu… there was a copy paste error in the code.. Now corrected.. it should work now. 🙂
LikeLike
Sukhbinder – Thanks for sharing the outcome of your efforts with the rest of us. This seems like exactly what I need for some hobby experimentation. I am a Python newbie and just use it for some simple scripting. Grabbing and running the code from your post above required quite some formatting to make it work in my environment, but I think I have it going now. However, it complains with the message : VtkPointCloud instance has no attribute ‘clearPoints’. Not sure where to go from here. Can you email me the source code, so I know the formatting is correct. Thanks again.
/DC
LikeLike
Ignore earlier message. I got it working. More formatting errors when I cut and pasted from Wordpess. Fixed now. Thanks.
/DC
LikeLike
hello!
I have the XYZ data of 10 particles at 100 time steps (all in a .csv file).
Now I wish to simulate the movement of these particles using ParaView, but for that I think I would have to first convert my data in a VTK format.
How do I go about doing this?
Any help would be great!
Thanks!
Rohit.
LikeLike
Pingback: Displaying Truss | SukhbinderSingh.com
Pingback: Visualizing 3d Triangles With Pure Matplotlib Function | SukhbinderSingh.com
Hello! Can you show example of xyz data of input file?
LikeLike
Hi Andrey.
Thanks for reading. The input file looks like the following
# comment 1
# comment 2
0.0 1.0 2.0
1.0 2.0 3.0
So the idea was the xyz file has 2 lines of comment.
You can modify the line using genfromtxt to suit the input you have.
Hope this helps.
LikeLike
Hi Sukhbinder! i was wondering if you know of a method to add a color map to a 3d vtk surface? thanks
LikeLike
Hi Perry
Please search for VTK in this blog and there is a post related to plotting a truss which uses the color map for 2D.
3D should be similar.
Thanks
LikeLike
Please consider updating this post,
The code provided here must be modified as you can see clearly wordpress replace quotes by the word: "es; it replace the less than sign by; <
After reformatting the code, the script fails because it is outdated (some class method no more exist, …etc)
The link given to dropbox is broken
LikeLike
Thanks Samir for bringing this to my notice.. vtk has fallen out of my radar for last couple of years. I will find time and update. Now why isn’t the Dropbox link working, that strange…
LikeLike
Hi, Thank you so much for your blog, I found very useful
I get your script modified for Python 3 and running, It takes couple of minutes to modify end get running. First able SetInput() method no longer available in the newest versions of VTK, then xrange for python 2 must be replaced to range in Python 3. for numpy genfromtxt(), “skip_header” named argument seems no longer available. (I removed and generated one text file with floats and no header or comments)..And last, for python3 parenthesis mos be added to use print(). Please take a look here https://vtk.org/Wiki/VTK/VTK_6_Migration/Replacement_of_SetInput and here
https://stackoverflow.com/questions/26369357/error-in-a-python-program-maybe-vtk-related-help-please
https://stackoverflow.com/questions/4799773/numpy-genfromtxt-method-works-in-windows-but-not-linux
I leave the code into pastebin in order to bring available to anyone -> https://pastebin.com/reu0dXYj
LikeLike
Thanks Ralvarez!!
LikeLike
I saw your post it is really helpful.
In case we do not have a vtk file and want to create a vtk dataset file using python. how can we do that ?
I tried most everything in the web (I presume I am going somewhere wrong if, you can provide a brief understanding regarding how to create a file and then add a scalar value to it would be helpful). Its basic so, need a clear understanding of it.
Your help will be highly appreciated.
LikeLike
Thank you very much Ralvarez
LikeLike
I keep finding this problem. It says it doesn’t recognize the SetInput attribute of the mapper. I run this in visual studio. The only changes I’ve made is replace the < with the correct symbols ” python displayxyz.py caixa1.pcd
Traceback (most recent call last):
File “displayxyz.py”, line 59, in
pointCloud = VtkPointCloud()
File “displayxyz.py”, line 12, in __init__
mapper.SetInput(self.vtkPolyData)
AttributeError: ‘vtkmodules.vtkRenderingOpenGL2.vtkOpenGLPolyDataMa’ object has no attribute ‘SetInput’
I really need your help, can you tell me whats wrong?
Thanks
LikeLike
Hi Miguel. Let me check this. The VTK api might have changed, can you let me know which version you are using.
I will update the code to work with the latest vtk soon as I get some time.
LikeLike
Hi Miguel
Please check the code here https://pastebin.com/reu0dXYj as shown in the comment below.
Thanks
LikeLike