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()
opacity

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")
opacity

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")
opacity

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()
My Interpolated Opacity Transfer Function

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)
opacity

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()
opacity

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()
opacity

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 23.840 seconds)

Gallery generated by Sphinx-Gallery