Note
Go to the end to download the full example code.
Volume Rendering#
Volume render uniform mesh types like pyvista.ImageData
or 3D
NumPy arrays.
This also explores how to extract a volume of interest (VOI) from a
pyvista.ImageData
using the
pyvista.ImageDataFilters.extract_subset()
filter.
from __future__ import annotations
import pyvista as pv
from pyvista import examples
# Download a volumetric dataset
vol = examples.download_knee_full()
vol
Simple Volume Render#
# A nice camera position
cpos = [(-381.74, -46.02, 216.54), (74.8305, 89.2905, 100.0), (0.23, 0.072, 0.97)]
vol.plot(volume=True, cmap='bone', cpos=cpos)
Opacity Mappings#
Or use the pyvista.Plotter.add_volume()
method like below.
Note that here we use a non-default opacity mapping to a sigmoid:
pl = pv.Plotter()
pl.add_volume(vol, cmap='bone', opacity='sigmoid')
pl.camera_position = cpos
pl.show()
You can also use a custom opacity mapping
We can also use a shading technique when volume rendering with the shade
option
Cool Volume Examples#
Here are a few more cool volume rendering examples.
Head Dataset#
head = examples.download_head()
pl = pv.Plotter()
pl.add_volume(head, cmap='cool', opacity='sigmoid_6', show_scalar_bar=False)
pl.camera_position = [(-228.0, -418.0, -158.0), (94.0, 122.0, 82.0), (-0.2, -0.3, 0.9)]
pl.camera.zoom(1.5)
pl.show()
Bolt-Nut MultiBlock Dataset#
Note
See how we set interpolation to 'linear'
here to smooth out scalars of
each individual cell to make a more appealing plot. Two actor are returned
by add_volume
because bolt_nut
is a pyvista.MultiBlock
dataset.
bolt_nut = examples.download_bolt_nut()
pl = pv.Plotter()
actors = pl.add_volume(bolt_nut, cmap='coolwarm', opacity='sigmoid_5', show_scalar_bar=False)
actors[0].prop.interpolation_type = 'linear'
actors[1].prop.interpolation_type = 'linear'
pl.camera_position = [(127.4, -68.3, 88.2), (30.3, 54.3, 26.0), (-0.25, 0.28, 0.93)]
cpos = pl.show(return_cpos=True)
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Exception ignored in: <function _BaseVolumeMapper.__del__ at 0x7f478b558b80>
Traceback (most recent call last):
File "/home/runner/work/pyvista/pyvista/pyvista/plotting/mapper.py", line 1149, in __del__
del self._lut
^^^^^^^^^
AttributeError: 'SmartVolumeMapper' object has no attribute '_lut'
Frog Dataset#
frog = examples.download_frog()
pl = pv.Plotter()
pl.add_volume(frog, cmap='viridis', opacity='sigmoid_6', show_scalar_bar=False)
pl.camera_position = [(929.0, 1067.0, -278.9), (249.5, 234.5, 101.25), (-0.2048, -0.2632, -0.9427)]
pl.camera.zoom(1.5)
pl.show()
Extracting a VOI#
Use the pyvista.ImageDataFilters.extract_subset()
filter to extract
a volume of interest/subset volume to volume render. This is ideal when
dealing with particularly large volumes and you want to volume render only
a specific region.
# Load a particularly large volume
large_vol = examples.download_damavand_volcano()
large_vol
Woah, that’s a big volume. We probably don’t want to volume render the whole thing. So let’s extract a region of interest under the volcano.
The region we will extract will be between nodes 175 and 200 on the x-axis, between nodes 105 and 132 on the y-axis, and between nodes 98 and 170 on the z-axis.
voi = large_vol.extract_subset([175, 200, 105, 132, 98, 170])
pl = pv.Plotter()
pl.add_mesh(large_vol.outline(), color='k')
pl.add_mesh(voi, cmap='magma')
pl.show()
Ah, much better. Let’s now volume render that region of interest.
pl = pv.Plotter()
pl.add_volume(voi, cmap='magma', clim=clim, opacity=opacity, opacity_unit_distance=2000)
pl.camera_position = [
(531554.5542909054, 3944331.800171338, 26563.04809259223),
(599088.1433822059, 3982089.287834022, -11965.14728669936),
(0.3738545892415734, 0.244312810377319, 0.8947312427698892),
]
pl.show()
Total running time of the script: (0 minutes 39.326 seconds)