Hi guys. First of all, thank you so much for developing vtkPlotter. I have been a VTK user (C++ and Python) for many years now and I found amazing what can be achieved using vtkPlotter with only a few lines of code.
Here is what I am working on. I have a time sequence of an object (closed mesh) with 32 timepoints. I want to animate the movement and deformation of this object in time. Usually I would export each timepoint as a vtk polydata file, open the sequence of files in paraview and play it. However, I want to do that in vtkPlotter if possible. The code bellow is my very first attempt -- no animation so far. Could you guys help me to improve it? I can help to turn this into an official example if you think it might be of interest of others. Thanks a lot,
n = 8
vp = Plotter()
coo = np.random.rand(n*12).reshape(n,12)
for i in range(n):
u = coo[i,3:6]
v = coo[i,6:9]
q = coo[i,9:12]
ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]), axis1=u, axis2=v, axis3=q)
scals = [i] * ell.N()
ell.pointColors(scals, vmin=0, vmax=n)
ell.VisibilityOff()
vp += ell
vp.show()
Hi @vianamp
thanks for your interest!
Actually the show() command should be inside the loop. Check out for example this:
from vtkplotter import *
import numpy as np
vp = Plotter(interactive=False)
coo = np.random.rand(32*12).reshape(32,12)
for i in range(len(coo)):
u = coo[i,3:6]
v = coo[i,6:9]
q = coo[i,9:12]
ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]),
axis1=u, axis2=v, axis3=q)
scals = [i] * ell.N()
ell.pointColors(scals, vmin=0, vmax=31)
vp += ell
vp.show()
interactive()

Let me know if you need more help. Also, you can find more examples of animations in example/simulations directory which may fit your need.
Thanks for quick reply. What if I need only one timepoint to be shown at the time? And also to keep the bounding box fixed at the largest size that fits all the objects?
Also, I got this error when I tried to run your code on a jupyter notebook:
AttributeError Traceback (most recent call last)
<ipython-input-12-4b069e1c07cd> in <module>()
13 vp.show()
14
---> 15 interactive()
~/anaconda3/envs/qcb/lib/python3.6/site-packages/vtkplotter/plotter.py in interactive()
259 if settings.plotter_instance:
260 if hasattr(settings.plotter_instance, 'interactor'):
--> 261 settings.plotter_instance.interactor.Start()
262 return settings.plotter_instance
263
AttributeError: 'NoneType' object has no attribute 'Start'
There are 2 ways of doing it:
vp.show(world, ell, resetcam=False)from vtkplotter import *
import numpy as np
vp = Plotter(interactive=False)
coo = np.random.rand(32*12).reshape(32,12)
world = Box([1,1,1], 5,5,5).wireframe().alpha(0) ##########
for i in range(len(coo)):
u = coo[i,3:6]
v = coo[i,6:9]
q = coo[i,9:12]
ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]),
axis1=u, axis2=v, axis3=q)
scals = [i] * ell.N()
ell.pointColors(scals, vmin=0, vmax=31)
vp.show(world, ell)
interactive()
About the jupyter thing indeed this a current limitation (or ... bug) due to how the K3D backend works...
One needs to collect the object returned by show() and then just expose it outside the loop...

I see what you mean. My final code looks like this:
np.random.seed(1234)
n = 8
vp = Plotter(interactive=False)
coo = np.random.rand(n*12).reshape(n,12)
world = Box([1,1,1], 5,5,5).wireframe().alpha(0)
for i in range(n):
u = coo[i,3:6]
v = coo[i,6:9]
q = coo[i,9:12]
ell = Ellipsoid(pos=(2.5*coo[i,0], 2.5*coo[i,1], 2.5*coo[i,2]), axis1=u, axis2=v, axis3=q)
scals = [i] * ell.N()
ell.pointColors(scals, vmin=0, vmax=n)
vp += ell
plt = vp.show(world, ell, resetcam=False)
plt
However, I don't actually see the animation. Only the last timepoint is shown.
Yes.. the jupyter functionality is still experimental and at the moment is not working well with loops.
It' s on my to-do list..
If you need to work in notebooks you still have the option of setting:
from vtkplotter import *
embedWindow(False)
then the normal vtk rendering window will pop up.
How to fix the viewing angle to the first frame. The object moves a little bit in the following gif.

Thanks~
@marcomusy
you can either add an invisible box:
vp += Box((1,1,1), length=5, width=5, height=5).wireframe().alpha(0)
or avoid resetting the camera later with
vp.show(resetcam=False)
in the ex. above, as the the object are added randomly, the first solution is probably the best.
Hi, marcomusy~
How to add a description for each frame like: "frame: {}/{}.format(current, all)"?
If I set by txt = Text(...) with background, it seems to get slower and slower, if I use vp.clear(txt), there will be flashes.
@LogWell
thanks for spotting the problem, I'll investigate that.