2. Color maps and transfer functions¶
One of the first things that any visualization tool user does when opening a new dataset and looking at the mesh is to color the mesh with some scalar data. Color mapping is a common visualization technique that maps data to color, and displays the colors in the rendered image. Of course, to map the data array to colors, we use a transfer function. A transfer function can also be used to map the data array to opacity for rendering translucent surfaces or for volume rendering. This chapter describes the basics of mapping data arrays to color and opacity.
2.1. The basics¶
Color mapping (which often also includes opacity mapping) goes by various names including scalar mapping and pseudo-coloring. The basic principle entails mapping data arrays to colors when rendering surface meshes or volumes. Since data arrays can have arbitrary values and types, you may want to define to which color a particular data value maps. This mapping is defined using what are called color maps or transfer functions. Since such mapping from data values to rendering primitives can be defined for not just colors, but opacity values as well, we will use the more generic term transfer functions.
Of course, there are cases when your data arrays indeed specify the
red-green-blue color values to use when rendering (i.e., not using a transfer
function at all). This can controlled using the
Map Scalars display property.
Refer to Chapter Fig. 4.5 for details. This
chapter relates to cases when
Map Scalars is enabled, i.e., when the transfer
function is being used to map arrays to colors and/or opacity.
In ParaView, you can set up a transfer function for each data array for both color and opacity separately. ParaView associates a transfer function with the data array identified by its name. The same transfer function is used when coloring with the same array in different 3D views or results from different stages in the pipeline. You can also use Section 2.2.1 to have independant color map by array name and representation.
For arrays with more than one component, such as vectors or tensors, you can specify whether to use the magnitude or a specific component for the color/opacity mapping. Similar to the transfer functions themselves, this selection of how to map a multi-component array to colors is also associated with the array name. Thus, two pipeline modules being colored with the arrays that have the same name will not only be using the same transfer functions for opacity and color, but also the component/magnitude selection.
Beginners find it easy to forget that the transfer function is associated with an array name and, hence, are surprised when changing the transfer function for a dataset being shown in one view affects other views as well. Using different transfer functions for the same variable is discouraged by design in ParaView, since it can lead to the misinterpretation of values. If you want to use different transfer functions, despite this caveat, you can use the Separate Color Map feature (see Section 2.2.1).
There are separate transfer functions for color and opacity. The opacity transfer function is used for volume rendering, and it is optional when used for surface renderings.
2.1.1. Color mapping in
You can pick an array to use for color mapping, using either the
panel or the
Active Variables Controls toolbar. You first select the array
with which to color and then select the component or magnitude for multi-component
arrays. ParaView will either use an existing transfer function or create a new
one for the selected array.
2.1.2. Color mapping in
Here’s a sample script for coloring using a data array from the
from paraview.simple import * # create a new 'ExodusIIReader' reader = ExodusIIReader(FileName=['disk_out_ref.ex2']) reader.PointVariables = ['V'] reader.ElementBlocks = ['Unnamed block ID: 1 Type: HEX8'] # show data in view display = Show(reader) # set scalar coloring ColorBy(display, ('POINTS', 'V')) # rescale color and/or opacity maps used to include current data range display.RescaleTransferFunctionToDataRange(True)
ColorBy function provided by the
simple module ensures that the color
and opacity transfer functions are set up correctly for the selected array, which
is using an existing one already associated with the array name or is creating a
new one. Passing
None as the second argument to
display scalar coloring.
2.2. Editing the transfer functions in
paraview, you use the
Color Map Editor to customize the
color and opacity transfer functions. You can toggle the
Color Map Editor
visibility using the View > Color Map Editor menu option.
As shown in Fig. 2.11, the panel follows a layout
similar to the
Properties panel. The panel shows the properties for the
transfer function, if any, used for coloring the active data source (or filter)
in the active view. If the active source if not visible in the active view, or
is not employing scalar coloring, then the panel will be empty.
Similar to the Properties panel, by default, the commonly used properties are
shown. You can toggle the visibility of advanced properties by using the
button. Additionally, you can search for a
particular property by typing its name in the
Whenever the transfer function is changed, we need to re-render, which may be
time consuming. By default, the panel requests a render on every change. To avoid
this, you can toggle the button. When unchecked,
you will need to manually update the panel using the
Render Views button.
The and buttons save the current color and opacity transfer function, with all its properties, as the default transfer function. ParaView will use it next time it needs to set up a transfer function to color a new data array. The button saves the transfer function as default for an array of the same name while the button saves the transfer function as default for all arrays. Note that this will not affect transfer functions already setup. Also this is saved across sessions, so ParaView will remember this even after restart.
2.2.1. Separate Color Map¶
In order to force ParaView to use a separate color map on the current Active Representation, click on the button shown in Fig. 2.12. A separate color map is not shared across representations by name, but is instead uniquely associated with the array name and the representation.
This can also easily be done in Python:
from paraview.simple import * Wavelet() wavelet1Display = Show() wavelet1Display.SetRepresentationType('Surface') # set scalar coloring ColorBy(wavelet1Display, 'RTData') # set the usage of a Separate Color Map wavelet1Display.UseSeparateColorMap = True # or use the ColorBy interface directly ColorBy(wavelet1Display, 'RTData', separate = True) # display the same data in another view for comparison with different color map # get layout layout1 = GetLayout() # split cell layout1.SplitHorizontal(0, 0.5) renderView1 = GetActiveView() # Create a new 'Render View' renderView2 = CreateView('RenderView') # place view in the layout layout1.AssignView(2, renderView2) # set active view SetActiveView(renderView2) wavelet2Display = Show() wavelet2Display.SetRepresentationType('Surface') # Use the ColorBy interface to create a separated color map ColorBy(wavelet2Display, 'RTData', separate = True) # get separate color transfer function/color map for 'RTData' separate_wavelet2Display_RTDataLUT = GetColorTransferFunction('RTData', wavelet2Display, separate=True) # Apply a preset using its name. separate_wavelet2Display_RTDataLUT.ApplyPreset('Cold and Hot', True) ResetCamera(renderView1) ResetCamera(renderView2) RenderAllViews()
2.2.2. Mapping data¶
Mapping Data group of properties controls how the data is mapped to
colors or opacity. The transfer function editor widgets are used to control the
transfer function for color and opacity. The panel always shows both the
transfer functions. Whether the opacity transfer function gets used depends on
When doing surface mesh rendering, it will be used only if
Enable opacity mapping for surfacesis checked
When doing volume rendering, the opacity mapping will always be used.
To map the data to color using a log scale, rather than a linear scale, check
Use log scale when mapping data to colors . It is assumed that the data
is in the non-zero, positive range. ParaView will report errors and try to
automatically fix the range if it is ever invalid for log mapping.
The range of a color map is a very important property that controls the mapping
of data values to colors. The range can be automatically updated in a number
of situations for convenience. How the range is updated is controlled by the
Automatic Rescale Range Mode property in the
Color Map Editor . When
Never is selected, the data range will never be updated automatically. When
Grow and update on 'Apply' is selected, ParaView will grow the color/opacity
map range to include the current data range every time you hit
Apply on the
Properties panel. Thus, when the data range changes, if the timestep is changed,
the color/opacity map range won’t be affected. To grow the range on change in
timestep as well, use the
Grow and update every timestep option. Now the
range will be updated on
Apply as well as when the timestep changes.
Grow indicates that the color/opacity map range will only be increased,
never shrunk, to include the current data range. If you want the range to
match the current data range exactly, then you should use the
update every timestep option. Now the range will be clamped to the exact data
range each time you hit
Apply on the
Properties panel or when the
timestep changes. The initial value for the
Automatic Rescale Range Mode
is controlled by the
Transfer Function Reset Mode in the
Settings dialog (see Section 11.1.1 ).
2.2.3. Transfer function editor¶
Using the transfer function editors is pretty straightforward. Control points
in the opacity editor widget and the color editor widget are independent of each
other. To select a control point, click on it. When selected, the control point
is highlighted with a red circle and data value associated with the control
point is shown in the
Data input box under the widget. Clicking in an empty area
will add a control point at that location. To move a control point, click on the
control point and drag it. You can fine tune the data value associated with the
selected control point using the
Data input box. To delete a control point,
select the control point and then type the Delete key. Note that the mouse pointer
should be within the transfer function widget for Qt to send the event to the
editor widget correctly. While the end control points cannot be moved or deleted,
you can rescale the entire transfer function to move the control
points, as is explained later.
In the opacity transfer function widget, you can move the control points vertically to control the opacity value associated with that control point. In the color transfer function widget, you can double click on the control point to pop up a color chooser widget to set the color associated with that control point.
The opacity transfer function widget also offers some control over the interpolation between the control points. Double click on a control point to show the interpolation control widget, which allows for changing the sharpness and midpoint that affect the interpolation. Click and drag the control points to see the change in interpolation.
The several control buttons on the right side of the transfer function widgets support the following actions:
: Rescales the color and opacity transfer functions using the data range from the data source selected in the Pipeline browser, i.e., the active source. This rescales the entire transfer function. Thus, all control points including the intermediate ones are proportionally adjusted to fit the new range.
: Rescales the color and opacity transfer functions using the range of values for the elements (cells or points) visible in the view. This operations assigns the entire range of colors to visible elements which may reveal patterns not visible otherwise.
: Inverts the color transfer function by moving the control points, e.g,. a red-to-green transfer function will be inverted to a green-to-red one. This only affects the color transfer function and leaves the opacity transfer function untouched.
: Saves the current color transfer function to presets. The
Color Presetmanager dialog pops up to let you name the transfer function and export the transfer function to a file. The opacity function can also be saved with the transfer function.
2.2.4. Color mapping parameters¶
Color Mapping Parameters group of properties provides additional
control over the color transfer function, including control over the color
interpolation space, which is either RGB, HSV, Lab, Diverging, or Lab/CIEDE2000.
To color data values falling below or above the range of the color map with special colors, enable the
Use Below Range Color and
Use Above Range Color options,
respectively. You can choose different colors for data falling on either side of
the range. When color mapping floating point arrays with NaNs, you can select
the color and opacity to use for NaN values. You can also affect whether the color transfer
function uses smooth interpolation or discretizes the map into a fixed
number of colors.
2.3. Editing the transfer functions in
pvpython, you control the transfer functions by getting access
to the transfer function objects and then changing properties on those. The
following script shows how you can access transfer functions objects.
from paraview.simple import * # You can access the color and opacity transfer functions # for a particular array as follows. These functions will # create new transfer functions if none exist. # The argument is the array name used to locate the transfer # functions. >>> colorMap = GetColorTransferFunction('Temp') >>> opacityMap = GetOpacityTransferFunction('Temp')
Once you have access to the color and opacity transfer functions, you can change properties on these similar to other sources, views, etc. Using the Python tracing capabilities to discover this API is highly recommended.
# Rescale transfer functions to a specific range >>> colorMap.RescaleTransferFunction(1.0, 19.9495) >>> opacityMap.RescaleTransferFunction(1.0, 19.9495) # Invert the color map. >>> colorMap.InvertTransferFunction() # Map color map to log-scale preserving relative positions for # control points >>> colorMap.MapControlPointsToLogSpace() >>> colorMap.UseLogScale = 1 # Return back to linear space. >>> colorMap.MapControlPointsToLinearSpace() >>> colorMap.UseLogScale = 0 # Change using of opacity mapping for surfaces >>> colorMap.EnableOpacityMapping = 1 # Explicitly specify color map control points # The value is a flattened list of tuples # (data-value, red, green, blue). The color components # must be in the range [0.0, 1.0] >>> colorMap.RGBPoints = [1.0, 0.705, 0.015, 0.149, 5.0, 0.865, 0.865, 0.865, 10.0, 0.627, 0.749, 1.0, 19.9495, 0.231373, 0.298039, 0.752941] # Similarly, for opacity map. The value here is # a flattened list of (data-value, opacity, mid-point, sharpness) >>> opacity.Points = [1.0, 0.0, 0.5, 0.0, 9.0, 0.404, 0.5, 0.0, 19.9495, 1.0, 0.5, 0.0] # Note, in both these cases the controls points are assumed to be sorted # based on the data values. Also, not setting the first and last # control point to have same data value can have unexpected artifacts # in the 'Color Map Editor' panel.
Oftentimes, you want to rescale the color and opacity maps to fit the current data ranges. You can do this as follows:
>>> source = GetActiveSource() # Update the pipeline, if it hasn't been updated already. >>> source.UpdatePipeline() # First, locate the display properties for the source of interest. >>> display = GetDisplayProperties() # Reset the color and opacity maps currently used by 'display' to # use the range for the array 'display' is using for color mapping. # This requires that the 'display' has been set to use scalar coloring # using an array that is available in the data generated. If not, you will # get errors. >>> display.RescaleTransferFunctionToDataRange()
2.4. Color legend¶
The color legend, also known as scalar bar or color bar, is designed to provide
the user information about which color corresponds to what data value in the
rendered view. You can toggle the visibility of the color legend corresponding
to the transfer function being shown/edit in the
Color Map Editor by using the
button near the top of
the panel. This button affects the visibility of the legend in the active view.
Fig. 2.15 shows the various components of the color legend. By default, the title is typically the name of the array (and component number or magnitude for non-scalar data arrays) being mapped. Automatically generated labels appear on one side of the color legend, while on the other side are annotations, optionally including start and end annotations depicting the minimum and maximum of the color legend range.
The color legend can be manipulated with the mouse. You can click and drag the legend to place it at any position in the view. Additionally, you can change the length of the legend by clicking and dragging the end-markers shown when you hover the mouse pointer over the legend.
2.4.1. Color legend parameters¶
You can edit the color legend parameters by clicking on the
button on the
Color Map Editor panel. This
will pop up the
Edit Color Legend Properties dialog that shows the available
parameters. Any changes made will affect only the particular color legend in
the active view.
The first few options in the
Edit Color Legend Properties control the
orientation and location of the color legend in the render view.
Auto Orient turns on automatic determination of the color legend’s orientation. The
color legend will change orientation to horizontal when it is dragged to the
bottom or the top of the render view, and it will change to vertical when it is
dragged to the left or right side. When disabled, you can choose the orientation
you want the color legend to have by choosing an option in the
Window Location option controls the location of the color legend in
the window; if the value
AnyLocation is selected, then the color
legend will not be forced into any particular position. The color legend can be
positioned by clicking and dragging it with the mouse in the render view,
Position property can be specified explicitly with
fractional coordinates that range from [0, 1] and represent the fraction of the window
width (or height) where the color legend’s bottom left corner should be placed. Note
that if the color legend is placed interactively with the mouse, the
Window Location option
will automatically change to
Besides the obvious changing of title text and font properties for the title, labels, and annotations, there are some other parameters that control the appearance of the color legend.
By default, the title is rotated 90 degrees counter-clockwise when the legend
is oriented vertically to better align with the legend. Checking the
Horizontal Title box forces the title of the color legend to be horizontal
regardless of color legend orientation.
Draw Annotations determines whether the annotations
(including the start and end annotations) are to be drawn at all.
Draw Nan Annotation results in the color legend showing the
NaN color set in the
Color Map Editor panel in a separate color box right beside the
color legend. The annotation text shown for that box can be modified by changing
Nan Annotation text.
Automatic Label Format is checked, ParaView will try to pick an optimal
representation for numerical values based on the value and available screen
space. By unchecking it, you can explicitly specify the
format to use for numeric values. To explicitly label values of interest, enable
Use Custom Labels option. You can specify exactly the labeled values
you wish to display in the table that appears when this option is chosen.
Color Bar Thickness is used to control the thickness of the legend. It is
defined in terms of points just like how font sizes are specified. Use
Length to explicitly set the length of the color bar. This property is defined
as a fraction in the range [0, 1] of the window width (when the color legend is
oriented horizontally) or height (when oriented vertically).
2.4.2. Color legend in
To show the color legend or scalar bar for the transfer function used for scalar mapping a source in a view, you can use API on its display properties:
>>> source = ... >>> display = GetDisplayProperties(source, view) # to show the color legend >>> display.SetScalarBarVisibility(view, True) # to hide the same >>> display.SetScalarBarVisibility(view, False)
To change the color legend properties as in Section 2.4.1, you need to first get access to the color legend object for the color transfer function in a particular view. These are analogous to display properties for a source in a view.
>>> colorMap = GetColorTransferFunction('Temp') # get the scalar bar in a view (akin to GetDisplayProperties) >>> scalarBar = GetScalarBar(colorMap, view) # Now, you can change properties on the scalar bar object. >>> scalarBar.TitleFontSize = 8 >>> scalarBar.DrawNanAnnotation = 1
Simply put, annotations allow users to put custom text at particular data values
in the color legend. The min and max data mapped value annotations are
automatically added. To add any other custom annotations, you can use the
Color Map Editor .
Since the list of annotations is an advanced property, you need to either toggle the
visibility of advanced properties using the icon
near the top of the panel or type
annotations in the
search box. That will show the
Annotations widget, which is basically a
list widget where users can enter key-value pairs, rather than value-annotation
pairs, as shown in Fig. 2.18.
You can use the buttons of the right on the widget to add/remove entries. Enter
the data value to annotate under the
Value column and then enter the text to
display at that value under the
You can use the Tab ↹ (tab) key to edit the next entry. Hitting Tab ↹ after editing the last entry in the table will automatically result in adding a new row, thus, making it easier to add bunch of annotations without having to click any buttons.
Some annotation texts may not show up on the legend. There are two possible reasons
an annotation may not be shown. First, the value added is outside the mapped range of the color transfer
Draw Annotations is unchecked in the
Color Legend Parameters
The and buttons can be used to fill the annotations widget with unique discrete values from a data array, if possible. Based on the number of distinct values present in the data array, this may not yield any result (Instead, a warning message will be shown). The data array values come either from the selected source object if you use the button or it comes from the visible pipeline objects if you use the button.
2.5.1. Annotations in
Annotations is a property on the color map object. You simply get access to the
color map of interest and then change the
>>> colorMap = GetColorTransferFunction('Temp') # Annotations are specified as a flattened list of tuples # (data-value, annotation-text) >>> colorMap.Annotations = ['1', 'Slow', '10', 'Fast']
2.6. Categorical colors¶
A picture is worth a thousand words, they say, so let’s just let the picture do the talking. Categorical color maps allow you to render visualizations as shown in Fig. 2.19.
When one thinks of scalar coloring, one is typically talking of mapping numerical values to colors. However, in some cases, the numerical values are not really numbers, but enumerations such as elements types and gear types (as in Fig. 2.19) or generally, speaking, categories. The traditional approach of using an interpolated color map specifying the range of values with which to color doesn’t really work here. While users could always play tricks with the number of discrete steps, multiple control points, and annotations, it is tedious and cumbersome.
Categorical color maps provide an elegant solution for
such cases. Instead of a continuous color transfer function, the user specifies a
set of discrete values and colors to use for those values. For any element where
the data value matches the values in the lookup table exactly,
the specified color; otherwise, the NaN color is used.
The color legend or scalar bar also switches to a new mode where it renders swatches with annotations, rather than a single bar. You can add custom annotations for each value in the lookup table.
2.6.1. Categorical Color: User Interface¶
paraview that the data array is to be treated as categories for coloring,
Interpret Values As Categories checkbox in the
Editor panel. As soon as that’s checked, the panel switches to categorical mode:
Mapping Data group is hidden, and the
Annotations group becomes a
non-advanced group, i.e., the annotations widget is visible even if the panel is
not showing advanced properties, as is shown in
The annotations widget will still show any annotations that may have been added earlier, or it may be empty if none were added. You can add annotations for data values as was the case before using the buttons on the side of the widget. This time, however, each annotation entry also has a column for color. If color has not been specified, a question mark icon will show up; otherwise, a color swatch will be shown. You can double click the color swatch or the question mark icon to specify the color to use for that entry. Alternatively, you can choose from a preset collection of categorical color maps by clicking the button.
As before, you can use Tab ↹ key to edit and add multiple values. Hence, you can first add all the values of interest in one pass and then pick a preset color map to set colors for the values added. If the preset has fewer colors than the annotated values, then the user may have to manually set the colors for those extra annotations.
Categorical color maps are designed for data arrays with enumerations, which are typically integer arrays. However, they can be used for arrays with floating point numbers as well. With floating point numbers, the value specified for annotation may not match the value in the dataset exactly, even when the user expects it to match. In that case, the NaN color will be used.
2.6.2. Categorical colors in
>>> categoricalColorMap = GetColorTransferFunction('Modes') >>> categoricalColorMap.InterpretValuesAsCategories = 1 # specify the labels for the categories. This is similar to how # other annotations are specified. >>> categoricalColorMap.Annotations = ['0', 'Alpha', '1', 'Beta'] # now, set the colors for each category. These are an ordered list # of flattened tuples (red, green, blue). The first color gets used for # the first annotation, second for second, and so on >>> categoricalColorMap.IndexedColors = [0.0, 0.0, 0.0, 0.89, 0.10, 0.10]