Colors

The vtkplotlib.colors module provides methods for:

  • Converting the various color types and matplotlib’s named colors to RGB(A) using as_rgb_a().

  • Creating and converting colormaps (usually abbreviated to cmap) to VTK’s equivalent vtkLookupTable class.

  • Texture mapping.

For the most part, these methods are used implicitly whenever you set the color or cmap arguments of any of vtkplotlib’s classes/methods/attributes. But if you’re doing something unusual then these may help.

New in version v1.3.0.


Individual Colors

as_rgb_a

vtkplotlib.colors.as_rgb_a(color=None, opacity=None)[source]

This method converts all the different ways a single color and opacity can be specified into the form (np.array([red, green, blue]), opacity).

The color argument can be:

  1. A string named color such as 'r' or 'red'. This uses matplotlib’s named color libraries. For a full list of available colors see the dicts BASE_COLORS, CSS4_COLORS and XKCD_COLORS from matplotlib.colors or vtkplotlib.colors.mpl_colors.

  2. A tuple or list of 3 or 4` scalars representing (red, green, blue) or (red, green, blue, alpha). red, green, blue and alpha can be from 0.0 to 1.0 or from 0 to 255 (inclusive).

  3. An html hex string in the form '#RRGGBB' or '#RRGGBBAA' where 'RR', 'GG', 'BB' and 'AA' are hexadecimal numbers from 00 to FF (0 to 255).

  4. A QtGui.QColor.

The opacity argument should be a scalar like those for the (r, g, b) from form 2 above values.

If an opacity if specified in both arguments then opacity argument overrides alpha values in color.

Note

Conventionally the values if they are from 0.0 to 1.0 they should be floats and if they are from 0 to 255 they should be ints. But this is so often not the case that this rule is unusable. This function divides by 255 if the scalars are integers and it sees anything greater than 1.

vtkplotlib.colors.mpl_colors

A dictionary containing all named colors known to vtkplotlib.


Colormaps

Colormaps are used to visualize scalar data as heatmaps. The color map determines which color represents each scalar value. In VTK, colormaps are called lookup tables and are of type vtk.vtkLookupTable.

Any vtkplotlib method that takes cmap argument can utilise a colormap.

import vtkplotlib as vpl
from stl.mesh import Mesh

# Load the usual rabbit.
mesh = Mesh.from_file(vpl.data.get_rabbit_stl())

fig = vpl.figure()

# Use the x values as scalars. Use matplotlib's "rainbow" colormap.
plot = vpl.mesh_plot(mesh, scalars=mesh.x, cmap="rainbow")
fig.show()

# The cmap is accessed as a vtkLookupTable via the cmap attribute.
plot.cmap
# (vtkCommonCorePython.vtkLookupTable)0000003C06D06F40

# Create and set a new cmap from a list of colors.
plot.cmap = ["red", "white", "green"]
fig.show()

# Explicitly set the scalar range
plot.scalar_range = -20, 20
fig.show()

# Set the scalar range back to automatic
plot.scalar_range = ...

Note that in Python 2.7 you can’t use ... except when indexing. Use Ellipsis instead.


as_vtk_cmap

vtkplotlib.colors.as_vtk_cmap(cmap, cache=True)[source]

Colormaps are generally converted implicitly from any valid format to a vtkLookupTable using this method. Any valid format is defined as the following:

  1. A string matplotlib colormap name such as 'RdYlGn'.

  2. Anything out of the matplotlib.cm package.

  3. A list of named colors such as ['red', 'white', 'blue']. See cmap_from_list for more details and flexibility.

  4. An (n, 3) or (n, 4) numpy.array of RGB(A) int or float values.

  5. A callable that takes an array of scalars and returns an array of form 4.

Unless specified otherwise using cache=False, named colormaps of form 1 are cached in vtkplotlib.colors.converted_cmaps. If you intend to modify the vtkLookupTable then it’s best not to allow caching.

Note

VTK doesn’t interpolate between colors. i.e if you use form 4 and only provide a short list of colors then the resulting heatmap will be block colors rather than a smooth gradient.

Note

Whilst VTK appears to support opacity gradients in the colormaps, it doesn’t actually use them. If your colormap says opacity should vary with scalars then the opacity is averaged for the plot.


cmap_from_list

vtkplotlib.colors.cmap_from_list(colors, opacities=None, scalars=None, resolution=None)[source]

Create a colormap from a list of colors. Unlike matplotlib’s matplotlib.colors.ListedColormap, this method will interpolate between the input colors to give a smooth map.

Parameters
  • colors (list) – A list of valid colors as defined by as_rgb_a().

  • opacities (float or numpy.ndarray) – Translucency or translucencies from 0.0 to 1.0.

  • scalars (numpy.ndarray) – Control scalars to correspond exact colors from color, defaults to np.arange(len(colors)).

  • resolution (int) – Number of colors in output, defaults to (len(colors) - 1) * 255 + 1.

Returns

An (n, 4) uint8 array of RGBA values.

Return type

numpy.ndarray

The output can be fed either to as_vtk_cmap() or passed directly as a cmap argument to any vtkplotlib method that takes one.


vtkLookupTable

VTK’s vtkLookupTable provides some useful functionality that you can’t access any other way. Assuming you have a lookup table called table you can use the following:

Methods

Meaning

table.GetBelowRangeColor()
table.SetBelowRangeColor()
table.GetUseBelowRangeColor()
table.SetUseBelowRangeColor()
Choose a color to use when given
a scalar below the scalar range.
This must be enabled explicitly to
use.
table.GetAboveRangeColor()
table.SetAboveRangeColor()
table.GetUseAboveRangeColor()
table.SetUseAboveRangeColor()
Choose a color to use when given
a scalar above the scalar range.
This must be enabled explicitly to
use.
table.GetNanColor()
table.SetNanColor()
Choose a color to use when given
a NaN scalar.

Note

The scalar range is not controlled by the lookup table.


Texture Maps

Texture maps are like colormaps but two dimensional. i.e Rather than feeding it a scalar and getting a color, you give it an x and y coordinate and get a color. Texture maps allow you to color surfaces realistically to look like fur or grass or brickwork by using a texture map containing a 2D image of that texture.

TextureMap

class vtkplotlib.colors.TextureMap(array, interpolate=False)[source]

Use a 2D image as a color lookup table.

Warning

This is still very much under development and requires a bit of monkey-wrenching to use. Currently only vtkplotlib.surface and vtkplotlib.PolyData have any support for it.

Parameters
Returns

A callable texturemap object.

Return type

vtkplotlib.colors.TextureMap

The TextureMap object can be called to look up the color at a coordinate(s). Like everything else in vtkplotlib, texture coordinates should be zipped into a single array of the form:

np.array([[x0, y0],
          [x1, y1],
          ...,
          [xn, yn]])

Unlike typical images, texture-map coordinates traditionally use the conventional (x, y) axes. i.e Right is x-increasing and up is y-increasing. Indices are always between 0 and 1 and are independent of the size of the image. To use texture-coordinates, pass an array with array.shape[-1] == 2 as the scalar argument to a plot command.

Typically texture-maps are found in some 3D file formats but integrating those is still under development. Texture-maps also play very well with parametric plots, namely vtkplotlib.surface using the 2 independent variables as the texture coordinates.

import vtkplotlib as vpl
import numpy as np

# Define the 2 independent variables
phi, theta = np.meshgrid(np.linspace(0, 2 * np.pi, 1024),
                         np.linspace(0, np.pi, 1024))

# Calculate the x, y, z values to form a sphere
x = np.cos(phi) * np.sin(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(theta)

# You can play around with this. The coordinates must be zipped
# together into one array with ``shape[-1] == 2``, hence the
# ``vpl.zip_axes``. And must be between 0 and 1, hence the ``% 1.0``.
texture_coords = (vpl.zip_axes(phi * 3, theta * 5) / np.pi) % 1.0

# Pick an image to use. There is a picture of a shark here if you
# don't have one available.
path = vpl.data.ICONS["Right"]
texture_map = vpl.TextureMap(path, interpolate=True)


# You could convert `texture_coords` to `colors` now using.
# colors = texture_map(texture_coords)
# then pass ``colors`` as the `scalars` argument instead.

vpl.surface(x, y, z,
            scalars=texture_coords,
            texture_map=texture_map)

vpl.show()

Misc

normalise

vtkplotlib.colors.normalise(colors, axis=None)[source]

Scale and translate RBG(A) values so that they are all between 0 and 1.

Parameters
  • colors (numpy.ndarray) – Array of colors.

  • axis (int) – Axis to reduce over, normally either -1 or None are sensible, defaults to None.

Returns

Normalised colors.

Return type

numpy.ndarray

The output should have the properties np.min(out, axis) == 0 and np.max(out, axis) == 1.

import vtkplotlib as vpl
import numpy as np

points = np.random.uniform(-30, 30, (300, 3))

# This would be an invalid way to color by position.
# vpl.scatter(points, color=points)

# A better way to color by position.
vpl.scatter(points, color=vpl.colors.normalise(points))
vpl.show()