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.
Note
This submodule was introduced in v1.3.0.
Individual Colors¶
as_rgb_a¶
-
vtkplotlib.colors.
as_rgb_a
(color=None, opacity=None)¶ 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:
- 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.keys().
- A tuple or list of 3 or 4 scalars representing (r, g, b) or (r, g, b, alpha). r, g, b, alpha can be from 0 to 1 or from 0 to 255 (inclusive).
- An html hex string in the form “#RRGGBB” or “#RRGGBBAA” where
"RR"
,"GG"
,"BB"
and"AA"
are hexadecimal numbers from 00 to FF. - A
PyQt5.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.
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)¶ Colormaps are generally converted implicitly from any valid format to a
vtk.vtkLookupTable
using this method. Any valid format is defined as the following:- A string matplotlib colormap name such as
'RdYlGn'
. - Anything out of the
matplotlib.cm
package. - A list of named colors such as
["red", "white", "blue"]
. Seecmap_from_list()
for more details and flexibility. - An
(n, 3)
or(n, 4)
numpy array of RGB(A) int or float values. - 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 invtkplotlib.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.
- A string matplotlib colormap name such as
cmap_from_list¶
-
vtkplotlib.colors.
cmap_from_list
(colors, opacities=None, scalars=None, resolution=None)¶ Create a colormap from a list of colors. Unlike matplotlib’s
ListedColormap
, this method will interpolate between the input colors to give a smooth map.Parameters: - colors (list of valid colors as defined by
as_rgb_a()
) – A list colors. - opacities (Scalar from 0 to 1 or array-like of scalars, optional) – Translucency or translucencies, defaults to
None
. - scalars (array-like with same length as colors, optional) – Control scalars to correspond exact colors from color, defaults to
None
. - resolution (int, optional) – Number of colors in output, defaults to
(len(points) - 1) * 255 + 1
.
Returns: An array of RGBA values.
Return type: np.ndarray
with shape(n, 4)
and dtypenp.uint8
The output can be fed either to
as_vtk_cmap()
or passed directly as a cmap argument to any vtkplotlib method that takes one.- colors (list of valid colors as defined by
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()
table.GetUseNanColor()
table.SetUseNanColor()
|
Choose a color to use when given
a NaN scalar.
This must be enabled explicitly to
use.
|
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)¶ 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
vpl.surface
andvpl.PolyData
have any support for it.Parameters: - array (filename, np.ndarray with shape (m, n, 3 or 4), PIL Image) – The image data. It is converted to an array if it isn’t one already.
- interpolate (bool, optional) – Allow interpolation between pixels, defaults to False.
Returns: A callable texturemap object.
Return type: vtkplotlib.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
vpl.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)¶ Scale and translate RBG(A) values so that they are all between 0 and 1.
Parameters: - colors (np.ndarray) – Array of colors.
- axis (int, optional) – Axis to reduce over, normally either
-1
orNone
are sensible, defaults toNone
.
Returns: Normalised colors.
Return type: np.ndarray
The output should have the properties
np.min(out, axis) == 0
andnp.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()