Plot with Opacity

Plot a mesh’s scalar array with an opacity transfer function or opacity mapping based on a scalar array.

# sphinx_gallery_thumbnail_number = 2
import pyvista as pv
from pyvista import examples

# Load St Helens DEM and warp the topography
image = examples.download_st_helens()
mesh = image.warp_by_scalar()

Global Value

You can also apply a global opacity value to the mesh by passing a single float between 0 and 1 which would enable you to see objects behind the mesh:

p = pv.Plotter()
p.add_mesh(image.contour(), line_width=5,)
p.add_mesh(mesh, opacity=0.85, color=True)
p.show()
../../_images/sphx_glr_opacity_001.png

Out:

[(582074.6534978079, 5134221.153497808, 21193.15349780787), (562835.0, 5114981.5, 1953.5), (0.0, 0.0, 1.0)]

Note that you can specify use_transparency=True to convert opacities to transparencies in any of the following examples.

Transfer Functions

It’s possible to apply an opacity mapping to any scalar array plotted. You can specify either a single static value to make the mesh transparent on all cells, or use a transfer function where the scalar array plotted is mapped to the opacity. We have several predefined transfer functions.

Opacity transfer functions are:

  • 'linear': linearly vary (increase) opacity across the plotted scalar range from low to high

  • 'linear_r': linearly vary (increase) opacity across the plotted scalar range from high to low

  • 'geom': on a log scale, vary (increase) opacity across the plotted scalar range from low to high

  • 'geom_r': on a log scale, vary (increase) opacity across the plotted scalar range from high to low

  • 'sigmoid': vary (increase) opacity on a sigmoidal s-curve across the plotted scalar range from low to high

  • 'sigmoid_r': vary (increase) opacity on a sigmoidal s-curve across the plotted scalar range from high to low

# Show the linear opacity transfer function
mesh.plot(opacity="linear")
../../_images/sphx_glr_opacity_002.png

Out:

[(581977.3046422418, 5134123.804642241, 21436.804642241805), (562835.0, 5114981.5, 2294.5), (0.0, 0.0, 1.0)]
# Show the sigmoid opacity transfer function
mesh.plot(opacity="sigmoid")
../../_images/sphx_glr_opacity_003.png

Out:

[(581977.3046422418, 5134123.804642241, 21436.804642241805), (562835.0, 5114981.5, 2294.5), (0.0, 0.0, 1.0)]

It’s also possible to use your own transfer function that will be linearly mapped to the scalar array plotted. For example, we can create an opacity mapping as:

opacity = [0, 0.2, 0.9, 0.6, 0.3]

When given a minimized opacity mapping like that above, PyVista interpolates it across a range of how many colors are shown when mapping the scalars. If scipy is available, then a quadratic interpolation is used - otherwise, a simple linear interpolation is used. Curious what that opacity transfer function looks like? You can fetch it:

# Have PyVista interpolate the transfer function
tf = pv.opacity_transfer_function(opacity, 256).astype(float) / 255.

import matplotlib.pyplot as plt
plt.plot(tf)
plt.title('My Interpolated Opacity Transfer Function')
plt.ylabel('Opacity')
plt.xlabel('Index along scalar mapping')
plt.show()
../../_images/sphx_glr_opacity_004.png

Out:

/home/travis/build/pyvista/pyvista/examples/02-plot/opacity.py:81: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
  plt.show()

That opacity mapping will have an opacity of 0.0 at the minimum scalar range, a value or 0.9 at the middle of the scalar range, and a value of 0.3 at the maximum of the scalar range:

mesh.plot(opacity=opacity)
../../_images/sphx_glr_opacity_005.png

Out:

[(581977.3046422418, 5134123.804642241, 21436.804642241805), (562835.0, 5114981.5, 2294.5), (0.0, 0.0, 1.0)]

Opacity mapping is often useful when plotting DICOM images. For example, download the sample knee DICOM image:

knee = examples.download_knee()

And here we inspect the DICOM image with a few different opacity mappings:

p = pv.Plotter(shape=(2, 2), border=False)

p.add_mesh(knee, cmap="bone", stitle="No Opacity")
p.view_xy()

p.subplot(0, 1)
p.add_mesh(knee, cmap="bone", opacity="linear", stitle="Linear Opacity")
p.view_xy()

p.subplot(1, 0)
p.add_mesh(knee, cmap="bone", opacity="sigmoid", stitle="Sigmoidal Opacity")
p.view_xy()

p.subplot(1, 1)
p.add_mesh(knee, cmap="bone", opacity="geom_r", stitle="Log Scale Opacity")
p.view_xy()

p.show()
../../_images/sphx_glr_opacity_006.png

Out:

[(109.78834672272205, 109.78834672272205, 599.8946826509293), (109.78834672272205, 109.78834672272205, 0.0), (0.0, 1.0, 0.0)]

Opacity by Array

You can also use a scalar array associated with the mesh to give each cell its own opacity/transparency value derived from a scalar field. For example, an uncertainty array from a modelling result could be used to hide regions of a mesh that are uncertain and highlight regions that are well resolved.

The following is a demonstration of plotting a mesh with colored values and using a second array to control the transparency of the mesh

model = examples.download_model_with_variance()
contours = model.contour(10, scalars='Temperature')
contours.array_names

Out:

['Temperature', 'Temperature_var']

Make sure to flag use_transparency=True since we want areas of high variance to have high transparency.

p = pv.Plotter(shape=(1,2))

p.subplot(0,0)
p.add_text('Opacity by Array')
p.add_mesh(contours.copy(), scalars='Temperature',
           opacity='Temperature_var',
           use_transparency=True,
           cmap='bwr')

p.subplot(0,1)
p.add_text('No Opacity')
p.add_mesh(contours, scalars='Temperature',
           cmap='bwr')
p.show()
../../_images/sphx_glr_opacity_007.png

Out:

[(375736.26585408027, 4300589.54710408, 38497.29710408029), (337038.96875, 4261892.25, -200.0), (0.0, 0.0, 1.0)]

Total running time of the script: ( 0 minutes 41.651 seconds)

Gallery generated by Sphinx-Gallery