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:
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 dictsBASE_COLORS
,CSS4_COLORS
andXKCD_COLORS
frommatplotlib.colors
orvtkplotlib.colors.mpl_colors
.A tuple or list of 3 or 4` scalars representing
(red, green, blue)
or(red, green, blue, alpha)
.red
,green
,blue
andalpha
can be from 0.0 to 1.0 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 from00
toFF
(0 to 255).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:
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.
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
The output can be fed either to
as_vtk_cmap()
or passed directly as a cmap argument to anyvtkplotlib
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
andvtkplotlib.PolyData
have any support for it.- Parameters
array (str or os.PathLike or numpy.ndarray or PIL.Image.Image) – The image data. It is converted to an array if it isn’t one already.
interpolate (bool) – Allow interpolation between pixels, defaults to False.
- Returns
A callable texturemap object.
- Return type
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
orNone
are sensible, defaults toNone
.
- Returns
Normalised colors.
- Return type
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()