Reputation: 11
I want to make a multi-window plot of varies scalars of 3D mesh and update it with new values.
Ques. 1 (resolved by setting key copy_mesh
)
However, when I am plotting multiple scalars with a same mesh in one window, a similar problem (subplots are sharing the colorlevels) to Ref happened (fig 1 and 2 with same mesh) .
I tried to reload the mesh , it goes right (fig 1 and 3).
Any idea what I am missing here would be greatly appreciated!
This are the code and image:
import pyvista as pv
from pyvista import examples
from pyvistaqt import BackgroundPlotter
shape = (3, 1)
plotter = BackgroundPlotter(shape=shape) # qt
# plotter = pv.Plotter()
plotter.subplot(0, 0)
sphere = pv.Sphere()
plotter.add_mesh(sphere, scalars=10*sphere.points[:, 2],scalar_bar_args={'title':'V1'})
plotter.subplot(1, 0)
plotter.add_mesh(sphere, scalars=sphere.points[:, 2],scalar_bar_args={'title':'V2'})
plotter.subplot(2, 0)
sphere = pv.Sphere() # if reload sphere it goes well
plotter.add_mesh(sphere, scalars=sphere.points[:, 2],scalar_bar_args={'title':'V3'})
# Display the window without qt
plotter.show() # break point
Ques. 2 (resolved by save plotter.mesh
)
Additionally, I tried to update each subplot (from fig1 to fig3) by various data. However, only the last one (fig3) can be updated by update_scalars
. The fig1 unchanged evenif subplot(0,0)
is used.
# it works
plotter.update_scalars(sphere.points[:,2]*5)
# it does not work to fig1 but work to fig3
plotter.subplot(0,0)
plotter.update_scalars(sphere.points[:,2]*5)
I note update_scalars()
default update latest mesh
if multi meshes exist
def update_scalars(self, scalars, mesh=None, render=True):
mesh : vtk.PolyData or vtk.UnstructuredGrid, optional
Object that has already been added to the Plotter. If
None, uses last added mesh.
Upvotes: 1
Views: 1591
Reputation: 35176
The problem is that plotting methods don't automatically make copies of their input meshes, because this would make a lot of big-data applications infeasible with PyVista due to the multiplication of memory footprint. But a single mesh object has a single set of active scalars at a time, so you can't directly reuse the same mesh with different sets of scalars. (This also means that the issue is different from what you linked, although the result looks the same.)
You have to copy your input mesh. You saw this work when you called pv.Sphere()
again: that creates a new mesh. You could also call sphere.copy()
when you pass it to the plotter. But actually the Plotter.add_mesh()
method has a copy_mesh
keyword parameter:
copy_mesh
:bool
, optionalIf
True
, a copy of the mesh will be made before adding it to the plotter. This is useful if you would like to add the same mesh to a plotter multiple times and display different scalars. Settingcopy_mesh
toFalse
is necessary if you would like to update the mesh after adding it to the plotter and have these updates rendered, e.g. by changing the active scalars or through an interactive widget. This should only be set toTrue
with caution. Defaults toFalse
. This is ignored if the input is avtkAlgorithm
subclass.
Note that the above description fits your use case perfectly.
This feature was added in this PR, so you need PyVista 0.35.3 or newer in order to use it. Otherwise you can just copy the mesh yourself.
Upvotes: 0