colorstools module
## colorstools Module Description
### Overview The colorstools module provides comprehensive functionality for working with colors in neuroimaging and scientific visualization contexts. It offers utilities for color validation, conversion, manipulation, and management of color lookup tables (LUTs) commonly used in FreeSurfer and other neuroimaging software packages.
### Core Functionality
Color Validation and Detection The module includes robust color validation functions that handle multiple input formats including hexadecimal strings, RGB arrays (both 0-255 and 0-1 ranges), numpy arrays, and Python lists. It provides intelligent detection of RGB value ranges and validates color formats across different representations.
Color Conversion and Transformation Extensive conversion utilities enable seamless transformation between different color formats (hex to RGB, RGB to hex, and normalized variants). The module supports batch conversions through functions like multi_hex2rgb() and multi_rgb2hex(), allowing efficient processing of large color datasets. Additional transformation capabilities include color inversion, lightening, darkening, and saturation adjustments performed in HSV color space.
Color Harmonization and Matching The harmonize_colors() function standardizes mixed-format color inputs into a consistent output format, essential for visualization pipelines that accept diverse color specifications. The module also provides color matching utilities to find the closest colors within a palette and generate distinguishable color schemes for categorical data visualization.
Color Lookup Table Management The ColorTableLoader class provides sophisticated handling of FreeSurfer-style color lookup tables (LUT files) and TSV-format color tables. It supports reading, writing, filtering, and exporting color tables in multiple formats. The class automatically detects file formats and handles headerlines, region codes, color specifications, and opacity values. It includes methods for converting between different color table formats and integrating with neuroimaging parcellation schemes.
Visualization Utilities The module includes functions for visualizing color palettes, displaying color swatches with labels, and creating colormaps. These utilities facilitate quality control of color schemes and enable interactive exploration of color tables in Jupyter notebooks through HTML rendering.
Terminal Output Formatting The bcolors class provides ANSI color codes for enhanced terminal output, enabling colored console messages for logging, debugging, and user feedback in command-line applications.
### Use Cases This module is particularly valuable for neuroimaging researchers working with brain parcellations, creating publication-quality figures, managing custom color schemes for anatomical regions, and developing visualization tools that require consistent color handling across different data formats and software packages.
- class clabtoolkit.colorstools.bcolors[source]
Bases:
objectThis class is used to define the colors for the terminal output. It can be used to print the output in different colors.
- HEADER = '\x1b[95m'
- OKBLUE = '\x1b[94m'
- OKGREEN = '\x1b[92m'
- OKYELLOW = '\x1b[93m'
- OKRED = '\x1b[91m'
- OKMAGENTA = '\x1b[95m'
- PURPLE = '\x1b[35m'
- OKCYAN = '\x1b[96m'
- DARKCYAN = '\x1b[36m'
- ORANGE = '\x1b[48:5:208m%s\x1b[m'
- OKWHITE = '\x1b[97m'
- DARKWHITE = '\x1b[37m'
- OKBLACK = '\x1b[30m'
- OKGRAY = '\x1b[90m'
- OKPURPLE = '\x1b[35m'
- WARNING = '\x1b[93m'
- FAIL = '\x1b[91m'
- ENDC = '\x1b[0m'
- BOLD = '\x1b[1m'
- ITALIC = '\x1b[3m'
- UNDERLINE = '\x1b[4m'
- DIM = '\x1b[2m'
- NORMAL = '\x1b[22m'
- RESET_ALL = '\x1b[0m'
- clabtoolkit.colorstools.is_color_like(color)[source]
Extended color validation that handles numpy arrays and Python lists. Supports both RGB (3 components) and RGBA (4 components) colors.
- Parameters:
color (Any) – The color to validate. Can be: - Hex string (e.g., “#FF5733” or “#FF5733FF”) - Numpy array ([R,G,B] or [R,G,B,A] as integers 0-255 or floats 0-1 or floats 0-255) - Python list/tuple ([R,G,B] or [R,G,B,A] as integers 0-255 or floats 0-1 or floats 0-255)
- Returns:
True if the color is valid, False otherwise.
- Return type:
Examples
>>> is_color_like("#FF5733") # Hex string True >>> is_color_like(np.array([255, 87, 51])) # Numpy array (int) True >>> is_color_like(np.array([255, 87, 51, 255])) # Numpy array with alpha True >>> is_color_like(np.array([1.0, 0.34, 0.2])) # Numpy array (float 0-1) True >>> is_color_like(np.array([70., 130., 180.])) # Numpy array (float 0-255) True >>> is_color_like([255, 87, 51]) # Python list (int) True >>> is_color_like((255, 128, 0, 128)) # Tuple with alpha True >>> is_color_like([1.0, 0.34, 0.5]) # Python list (float 0-1) True >>> is_color_like([255.0, 128.0, 0.0]) # Integer-valued floats True >>> is_color_like((255, 128, 0)) # Tuple True >>> is_color_like("invalid_color") False >>> is_color_like([256, 0, 0]) # Out of range False
- clabtoolkit.colorstools.detect_rgb_range(rgb)[source]
Detect if an RGB array uses 0-255 or 0-1 range.
This function analyzes RGB color values to determine whether they follow the 0-255 integer format (8-bit) or the 0-1 float format (normalized).
- Parameters:
rgb (Any) – RGB color array/list containing 3 numeric values [R, G, B]. Expected formats: [255, 128, 0] or [1.0, 0.5, 0.0]
- Returns:
“0-255” if any value is greater than 1
”0-1” if all values are between 0 and 1 (inclusive)
”invalid” if input is malformed or values are outside valid ranges
- Return type:
- Raises:
None – This function does not raise any exceptions. Invalid inputs return “invalid” instead of raising errors.
Examples
>>> detect_rgb_range([255, 128, 0]) '0-255' >>> detect_rgb_range([1.0, 0.5, 0.0]) '0-1' >>> detect_rgb_range([0, 1, 0]) '0-1' >>> detect_rgb_range([255, 0.5, 128]) 'invalid' >>> detect_rgb_range([300, 200, 100]) 'invalid' >>> detect_rgb_range([0.0, 0.0, 0.0]) '0-1' >>> detect_rgb_range([255, 255, 255]) '0-255' >>> detect_rgb_range([2, 1, 0]) '0-255' >>> detect_rgb_range("not_a_list") 'invalid' >>> detect_rgb_range([255, 128]) 'invalid'
Notes
Expects exactly 3 numeric values (R, G, B)
Any value greater than 1 classifies the array as “0-255” range
All values between 0-1 (inclusive) classify the array as “0-1” range
Combinations like [0, 1, 0] are treated as “0-1” range
The 0-255 validator only accepts whole numbers (integers or floats like 128.0)
The 0-1 validator accepts any numeric values in the 0-1 range
Mixed ranges (e.g., [255, 0.5, 128]) are considered invalid
Out-of-range values (negative or > 255) result in “invalid” classification
- clabtoolkit.colorstools.is_valid_rgb_255(rgb)[source]
Check if RGB array contains valid 0-255 range values.
This function validates RGB color values in the 0-255 range. It accepts integers and integer-valued floats (e.g., 255.0), but rejects fractional values or values outside the valid range.
- Parameters:
rgb (Any) – RGB color array/list to validate. Can be: - Numpy array with 3 elements - Python list with 3 elements - Python tuple with 3 elements
- Returns:
True if all values are valid 0-255 range integers (or integer-valued floats), False otherwise
- Return type:
Examples
>>> is_valid_rgb_255([255, 128, 0]) True >>> is_valid_rgb_255([0, 0, 0]) True >>> is_valid_rgb_255([1, 1, 1]) True >>> is_valid_rgb_255([128.0, 200.0, 50.0]) True >>> is_valid_rgb_255((255, 128, 0)) True >>> is_valid_rgb_255(np.array([255, 128, 0])) True >>> is_valid_rgb_255(np.array([70., 130., 180.])) True >>> is_valid_rgb_255([np.int64(255), 128, 0]) True >>> is_valid_rgb_255([0.5, 0.3, 0.8]) False >>> is_valid_rgb_255([128.5, 200.7, 50.2]) False >>> is_valid_rgb_255([300, 200, 100]) False >>> is_valid_rgb_255([-1, 128, 0]) False >>> is_valid_rgb_255([255, 128]) False
Notes
Accepts both Python native types and numpy types
Integer-valued floats (e.g., 255.0) are considered valid
Fractional floats (e.g., 128.5) are rejected
Values must be in the inclusive range [0, 255]
- clabtoolkit.colorstools.is_valid_rgb_01(rgb)[source]
Check if RGB array contains valid 0-1 range values.
This function validates RGB color values in the 0-1 normalized range. It accepts floats and integers (0 or 1 only) in the valid range.
- Parameters:
rgb (Any) – RGB color array/list to validate. Can be: - Numpy array with 3 elements - Python list with 3 elements - Python tuple with 3 elements
- Returns:
True if all values are in 0-1 range, False otherwise
- Return type:
Examples
>>> is_valid_rgb_01([1.0, 0.5, 0.0]) True >>> is_valid_rgb_01([0.0, 0.0, 0.0]) True >>> is_valid_rgb_01([1.0, 1.0, 1.0]) True >>> is_valid_rgb_01([0, 0, 0]) True >>> is_valid_rgb_01([1, 1, 1]) True >>> is_valid_rgb_01([0, 1, 0]) True >>> is_valid_rgb_01((1.0, 0.5, 0.0)) True >>> is_valid_rgb_01(np.array([1.0, 0.5, 0.0])) True >>> is_valid_rgb_01(np.array([0, 1, 0])) True >>> is_valid_rgb_01([np.float64(1.0), 0.5, 0.0]) True >>> is_valid_rgb_01([255, 128, 0]) False >>> is_valid_rgb_01([1.5, 0.5, 0.2]) False >>> is_valid_rgb_01([-0.1, 0.5, 0.2]) False >>> is_valid_rgb_01([0, 0]) False
Notes
Accepts both Python native types and numpy types
Integer values must be 0 or 1 only
Float values can be any value in the range [0.0, 1.0]
Values must be in the inclusive range [0, 1]
- clabtoolkit.colorstools.normalize_rgb(rgb)[source]
Convert RGB array to 0-1 range regardless of input format.
- Parameters:
rgb (Any) – RGB color array in either 0-255 or 0-1 format
- Returns:
RGB values normalized to 0-1 range, or None if invalid input
- Return type:
List[float] or None
- clabtoolkit.colorstools.rgb2hex(r, g, b)[source]
Convert RGB values to hexadecimal color code. Handles both integer (0-255) and normalized float (0-1) inputs.
- Parameters:
- Returns:
Hexadecimal color code in lowercase (e.g., “#ff0000”)
- Return type:
- Raises:
ValueError – If values are outside valid ranges (either 0-255 or 0-1)
TypeError – If input types are mixed (some ints and some floats)
Examples
>>> rgb2hex(255, 0, 0) # Integer inputs '#ff0000'
>>> rgb2hex(1.0, 0.0, 0.0) # Normalized float inputs '#ff0000'
>>> rgb2hex(0.5, 0.0, 1.0) # Mixed range '#7f00ff'
- clabtoolkit.colorstools.multi_rgb2hex(colors)[source]
Function to convert rgb to hex for an array of colors. Note: If there are already elements in hexadecimal format the will not be transformed.
- Parameters:
colors (list or numpy array) – List of rgb colors
- Returns:
hexcodes – List of hexadecimal codes for the colors
- Return type:
Examples
>>> colors = [[255, 0, 0], [0, 255, 0], [0, 0, 255]] >>> hexcodes = multi_rgb2hex(colors) >>> print(hexcodes) # Output: ['#ff0000', '#00ff00', '#0000ff']
- clabtoolkit.colorstools.is_valid_hex_color(hex_color)[source]
Strict validation that requires # prefix and only allows 6-digit format.
This function validates hexadecimal color codes using a strict format that requires exactly 6 hexadecimal digits preceded by a hash (#) symbol.
- Parameters:
hex_color (str) – The hex color string to validate. Must be in the format #RRGGBB where R, G, B are hexadecimal digits (0-9, A-F, a-f).
- Returns:
True if the input is a valid 6-digit hex color with # prefix, False otherwise.
- Return type:
- Raises:
None – This function does not raise any exceptions. Invalid inputs return False instead of raising errors.
Examples
>>> is_valid_hex_color("#FF0000") True >>> is_valid_hex_color("#00FF00") True >>> is_valid_hex_color("#0000FF") True >>> is_valid_hex_color("#ffffff") True >>> is_valid_hex_color("#ABC123") True >>> is_valid_hex_color_strict("#FFF") False >>> is_valid_hex_color("FF0000") False >>> is_valid_hex_color("#GG0000") False >>> is_valid_hex_color("#FF0000FF") False >>> is_valid_hex_color("") False >>> is_valid_hex_color(None) False >>> is_valid_hex_color(123) False
Notes
Only accepts 6-digit hexadecimal format (e.g., #RRGGBB)
Requires the # prefix
Case-insensitive for hex digits (A-F or a-f)
Does not accept 3-digit shorthand (e.g., #FFF)
Does not accept 8-digit format with alpha channel
Non-string inputs return False
- clabtoolkit.colorstools.hex2rgb(hexcode)[source]
Function to convert hex to rgb
- Parameters:
hexcode (str) – Hexadecimal code for the color
- Returns:
Tuple with the rgb values
- Return type:
Examples
>>> hexcode = "#FF5733" >>> rgb = hex2rgb(hexcode) >>> print(rgb) # Output: (255, 87, 51)
- clabtoolkit.colorstools.multi_hex2rgb(hexcodes)[source]
Function to convert a list of colores in hexadecimal format to rgb format.
- Parameters:
hexcodes (list) – List of hexadecimal codes for the colors
- Returns:
rgb_list – Array of rgb values
- Return type:
np.array
Examples
>>> hexcodes = ["#FF5733", "#33FF57", "#3357FF"] >>> rgb_list = multi_hex2rgb(hexcodes) >>> print(rgb_list) # Output: [[255, 87, 51], [51, 255, 87], [51, 87, 255]]
- clabtoolkit.colorstools.invert_colors(colors)[source]
Invert colors while maintaining the original input format and value ranges.
- Parameters:
colors (list or numpy array) – Input colors in any of these formats: - Hex strings (e.g., “#FF5733”) - Python lists ([R,G,B] as integers 0-255 or floats 0-1) - Numpy arrays (integers 0-255 or floats 0-1)
- Returns:
Inverted colors in the same format and range as input
- Return type:
Examples
>>> invert_colors([np.array([0.0, 0.0, 1.0]), np.array([0, 255, 243])]) [array([1., 1., 0.]), array([255, 0, 12])]
- clabtoolkit.colorstools.harmonize_colors(colors, output_format='hex')[source]
Convert all colors in a list to a consistent format. Handles hex strings, RGB/RGBA lists, tuples, and numpy arrays (both 0-255 and 0-1 ranges). Note: Alpha channel is discarded if present.
- Parameters:
colors (list, numpy array, str, or tuple) –
Input colors in various formats: - Single color: str, list, tuple, or numpy array - Multiple colors: list or numpy array containing:
Hex strings (e.g., “#FF5733”)
Python lists or tuples ([R,G,B] or [R,G,B,A] as integers 0-255 or floats 0-1)
Numpy arrays (integers 0-255 or floats 0-1)
output_format (str, optional) – Output format (‘hex’, ‘rgb’, or ‘rgbnorm’), defaults to ‘hex’ - ‘hex’: returns hexadecimal strings (e.g., ‘#ff5733’) - ‘rgb’: returns RGB arrays with values 0-255 (uint8) - ‘rgbnorm’: returns normalized RGB arrays with values 0.0-1.0 (float64)
- Returns:
If output_format is ‘hex’: List of hexadecimal color strings
If output_format is ‘rgb’ or ‘rgbnorm’: 2D numpy array where each row is a color
- Return type:
Union[List[str], np.ndarray]
Examples
>>> colors = ["#FF5733", [255, 87, 51], (51, 87, 255)] >>> harmonize_colors(colors) ['#ff5733', '#ff5733', '#3357ff']
>>> colors = [(255, 87, 51, 255), (51, 87, 255, 128)] # RGBA >>> harmonize_colors(colors) ['#ff5733', '#3357ff']
>>> harmonize_colors(colors, output_format='rgb') array([[255, 87, 51], [255, 87, 51], [ 51, 87, 255]], dtype=uint8)
>>> harmonize_colors(colors, output_format='rgbnorm') array([[1. , 0.34117647, 0.2 ], [1. , 0.34117647, 0.2 ], [0.2 , 0.34117647, 1. ]])
>>> # Single color input >>> harmonize_colors((255, 87, 51)) ['#ff5733']
- clabtoolkit.colorstools.readjust_colors(colors, output_format='rgb')[source]
Function to readjust the colors to a certain format. It is just a wrapper from harmonize_colors function.
- Parameters:
colors (list or numpy array) – List of colors
- Returns:
out_colors – List of colors in the desired format
- Return type:
list or numpy array
Examples
>>> colors = ["#FF5733", [255, 87, 51], np.array([51, 87, 255])] >>> out_colors = readjust_colors(colors, output_format='hex') >>> print(out_colors) # Output: ['#ff5733', '#ff5733', '#3357ff']
>>> out_colors = readjust_colors(colors, output_format='rgb') >>> print(out_colors) # Output: [[255, 87, 51], [255, 87, 51], [51, 87, 255]]
- clabtoolkit.colorstools.create_random_colors(n, output_format='rgb', cmap=None, random_seed=None)[source]
Generate n colors either randomly or from a specified matplotlib colormap.
This function creates a collection of colors that can be used for data visualization, plotting, or other applications requiring distinct color schemes. Colors can be generated randomly or sampled from matplotlib colormaps for better visual harmony.
- Parameters:
n (int) – Number of colors to generate. Must be a positive integer.
output_format (str, default "rgb") – Format of the output colors. Supported formats: - “rgb”: RGB values as integers in range [0, 255] - “rgbnorm”: RGB values as floats in range [0.0, 1.0] - “hex”: Hexadecimal color strings (e.g., “#FF5733”)
cmap (str or None, default None) – Name of matplotlib colormap to use for color generation. If None, colors are generated randomly. Popular options include: - “viridis”, “plasma”, “inferno”, “magma” (perceptually uniform) - “PiYG”, “RdYlBu”, “Spectral” (diverging) - “Set1”, “Set2”, “tab10” (qualitative) - “Blues”, “Reds”, “Greens” (sequential) See matplotlib.pyplot.colormaps() for full list.
random_seed (int or None, default None) – Seed for random number generator to ensure reproducible results. Only used when cmap is None.
- Returns:
colors – Generated colors in the specified format: - If output_format is “hex”: list of hex color strings - If output_format is “rgb” or “rgbnorm”: numpy array of shape (n, 3)
- Return type:
list of str or numpy.ndarray
- Raises:
ValueError – If output_format is not one of the supported formats. If n is not a positive integer. If cmap is not a valid matplotlib colormap name.
TypeError – If n is not an integer.
Examples
Generate random colors:
>>> colors = create_random_colors(3, output_format="hex") >>> print(colors) # ['#A1B2C3', '#D4E5F6', '#789ABC']
>>> colors = create_random_colors(3, output_format="rgb") >>> print(colors) # [[161, 178, 195], [212, 229, 246], [120, 154, 188]]
Generate colors from a colormap:
>>> colors = create_random_colors(5, output_format="hex", cmap="PiYG") >>> print(colors) # ['#8E0152', '#C994C7', '#F7F7F7', '#A1DAB4', '#276419']
>>> colors = create_random_colors(4, output_format="rgbnorm", cmap="viridis") >>> print(colors) # [[0.267, 0.005, 0.329], [0.229, 0.322, 0.545], ...]
Notes
When using a colormap, colors are evenly spaced across the colormap range
Random colors are generated uniformly across RGB space and may not be
visually harmonious - For better visual results with random colors, consider using the harmonize_colors() function (if available) - Colormaps provide better perceptual uniformity and accessibility
- clabtoolkit.colorstools.get_colormaps_names(n, cmap_type='sequential')[source]
Get a list of colormap names from matplotlib. If n exceeds available colormaps, the list repeats. It can return either sequential or diverging colormaps.
- Parameters:
- Returns:
List of colormap names (repeats if n exceeds available colormaps)
- Return type:
Examples
>>> get_colormaps_names(5, cmap_type="sequential") ['viridis', 'plasma', 'inferno', 'magma', 'cividis']
>>> get_colormaps_names(3, cmap_type="diverging") ['PiYG', 'PRGn', 'BrBG']
Notes
Uses matplotlib’s built-in colormaps
If n exceeds available colormaps, the list repeats to fulfill the request
- clabtoolkit.colorstools.create_lut_dictionary(parc_values)[source]
Create a lookup table (LUT) dictionary mapping parcel values to colors.
- Parameters:
parc_values (List[int]) – List of integer parcel values.
- Returns:
Dictionary with keys: - “index”: List of parcel IDs (excluding background id 0) - “name”: List of region names (e.g., “Region_1”, “Region_2”, …) - “color”: List of hex color codes corresponding to each parcel ID
- Return type:
Examples
>>> parc_values = [0, 1, 2, 3, 4] >>> lut_dict = create_lut_dictionary(parc_values) >>> print(lut_dict) {'index': [1, 2, 3, 4], 'name': ['Region_1', 'Region_2', 'Region_3', 'Region_4'], 'color': ['#e6194b', '#3cb44b', '#ffe119', '#0082c8']}
- clabtoolkit.colorstools.create_distinguishable_colors(n, output_format='rgb', exclude_colors=None, lightness_range=(0.4, 0.85), saturation_range=(0.5, 1.0), random_seed=None)[source]
Generate n maximally distinguishable colors using perceptual color spacing.
This function creates colors that are as visually distinct as possible from each other, making them ideal for categorical data visualization, plots with many categories, or any application requiring easily distinguishable colors.
The algorithm uses HSV color space to distribute colors evenly across the hue spectrum while maintaining good saturation and lightness values for visibility. For very small sets (n ≤ 10), it can optionally use predefined maximally distinct color sets based on color theory research.
- Parameters:
n (int) – Number of colors to generate. Must be a positive integer.
output_format (str, default "rgb") – Format of the output colors. Supported formats: - “rgb”: RGB values as integers in range [0, 255] - “rgbnorm”: RGB values as floats in range [0.0, 1.0] - “hex”: Hexadecimal color strings (e.g., “#FF5733”)
exclude_colors (list of str or list of tuples, optional) – Colors to avoid when generating the palette. Can be hex strings or RGB tuples. The algorithm will try to maximize distance from these colors.
lightness_range (tuple of float, default (0.4, 0.85)) – Range of lightness (V in HSV) to use, as (min, max) in [0, 1]. Values closer to 0 are darker, closer to 1 are lighter. Default range avoids very dark and very light colors for better visibility.
saturation_range (tuple of float, default (0.5, 1.0)) – Range of saturation (S in HSV) to use, as (min, max) in [0, 1]. Values closer to 0 are more gray, closer to 1 are more vivid. Default range ensures colors are vibrant and easily distinguishable.
random_seed (int or None, default None) – Seed for random number generator for reproducible saturation/lightness variations. If None, variations will be non-deterministic.
- Returns:
colors – Generated colors in the specified format: - If output_format is “hex”: list of hex color strings - If output_format is “rgb” or “rgbnorm”: numpy array of shape (n, 3)
- Return type:
list of str or numpy.ndarray
- Raises:
ValueError – If output_format is not one of the supported formats. If n is not a positive integer. If lightness_range or saturation_range values are not in [0, 1].
TypeError – If n is not an integer.
Examples
Generate distinguishable colors for a categorical plot:
>>> colors = create_distinguishable_colors(5, output_format="hex") >>> print(colors) ['#E63946', '#06FFA5', '#3A86FF', '#FFBE0B', '#8338EC']
>>> colors = create_distinguishable_colors(8, output_format="rgb") >>> print(colors.shape) (8, 3)
Generate colors with custom lightness for dark backgrounds:
>>> colors = create_distinguishable_colors( ... 6, ... output_format="hex", ... lightness_range=(0.6, 0.95), ... saturation_range=(0.7, 1.0) ... )
Exclude specific colors (e.g., avoid red):
>>> colors = create_distinguishable_colors( ... 4, ... output_format="hex", ... exclude_colors=["#FF0000", "#CC0000"] ... )
Notes
Colors are distributed evenly across the hue spectrum (360 degrees)
Saturation and lightness are varied slightly to increase distinctiveness
The algorithm prioritizes perceptual difference over aesthetic harmony
For small sets (n ≤ 6), consider also trying matplotlib’s “tab10” colormap
with create_random_colors(n, cmap=”tab10”) for comparison - Maximum recommended n is around 20-30 for truly distinguishable colors; beyond that, some colors will inevitably appear similar
See also
create_random_colorsGenerate random or colormap-based colors
matplotlib.colors.rgb_to_hsvConvert RGB to HSV color space
- clabtoolkit.colorstools.get_predefined_distinguishable_colors(n, output_format='rgb')[source]
Get a predefined set of maximally distinguishable colors.
This function returns carefully selected colors that are known to be highly distinguishable based on color theory research. Available for up to 20 colors.
- Parameters:
- Returns:
colors – The predefined distinguishable colors.
- Return type:
Notes
Based on Kenneth Kelly’s 22 colors of maximum contrast, optimized for both color-normal and color-blind viewers.
- clabtoolkit.colorstools.colortable_visualization(colortable, region_names=None, columns=2, export_path=None, title='Color Table', alternating_bg=False)[source]
Color table visualization. Generates a PNG image displaying a FreeSurfer-style color table.
- Parameters:
colortable (array-like, str, or Path) – Can be one of: - Array-like with shape (N, 3), (N, 4), or (N, 5): [R, G, B] or [R, G, B, Alpha] or [R, G, B, Alpha, Value] - String or Path to a LUT file (.txt, .lut) or TSV file (.tsv)
region_names (str or list of str, optional) – Region names corresponding to each row. If None and loading from file, uses the names from the file. Default is None.
columns (int, default=2) – Number of columns in layout.
export_path (str, optional) – Path to save PNG file.
title (str, default="Color Table") – Title displayed at the top.
alternating_bg (bool, default=False) – Whether to shade alternating rows for readability.
- Returns:
fig – Matplotlib figure object.
- Return type:
matplotlib.figure.Figure
- Raises:
ValueError – If colortable shape is invalid or region_names length mismatch.
TypeError – If region_names is not a string or a list of strings.
FileNotFoundError – If the specified file path does not exist.
Examples
>>> # Example 1: Using an array >>> colortable = [[255, 0, 0], [0, 255, 0], [0, 0, 255]] >>> region_names = ["Region 1", "Region 2", "Region 3"] >>> fig = colortable_visualization(colortable, region_names, ... columns=1, title="My Color Table") >>> plt.show()
>>> # Example 2: Loading from a LUT file >>> fig = colortable_visualization('FreeSurferColorLUT.txt', ... columns=2, title="FreeSurfer Regions") >>> plt.show()
>>> # Example 3: Loading from file with custom names >>> custom_names = ["Custom 1", "Custom 2", "Custom 3"] >>> fig = colortable_visualization('regions.tsv', ... region_names=custom_names, columns=1) >>> plt.show()
- clabtoolkit.colorstools.get_colors_from_colortable(labels, reg_ctable)[source]
Create per-vertex RGBA colors based on parcellation labels.
Assigns colors to vertices based on their parcellation region using the color table information.
- Parameters:
labels (np.ndarray) – Array of parcellation labels for each vertex.
reg_ctable (np.ndarray) – Color table with shape (N, 5) where first 3 columns are RGB values and column 4 contains region labels.
- Returns:
colors – Array of RGB colors for each vertex with shape (num_vertices, 3). Default color is gray (240, 240, 240) for unlabeled vertices.
- Return type:
np.ndarray
Examples
>>> # Create vertex colors for visualization over a surface mesh >>> colors = get_colors_from_colortable(vertex_labels, color_table) >>> print(f"Colors shape: {colors.shape}") # (num_vertices, 3)
- clabtoolkit.colorstools.values2colors(values, cmap='viridis', output_format='hex', invert_cl=False, invert_clmap=False, vmin=None, vmax=None, range_min=None, range_max=None, range_color=(200, 200, 200))[source]
Map numerical values to colors using a specified colormap with optional inversions.
This function takes a list or array of numerical values and maps them to colors using matplotlib colormaps. It provides options to invert the colormap gradient and/or invert the resulting colors to their complements.
- Parameters:
values (list or numpy.ndarray) – Numerical values to map to colors. Can be integers or floats.
cmap (str, default "viridis") – Name of matplotlib colormap to use for color generation.
output_format (str, default "hex") – Format of the output colors. Supported formats: - “hex”: Hexadecimal color strings (e.g., “#FF5733”) - “rgb”: RGB values as integers in range [0, 255] - “rgbnorm”: RGB values as floats in range [0.0, 1.0]
invert_cl (bool, default False) – If True, return the complementary colors instead of the original ones.
invert_clmap (bool, default False) – If True, invert the gradient of the colormap before mapping values.
vmin (float or None, default None) – Minimum value for colormap normalization. If None, uses range_min if provided, otherwise uses min of in-range values.
vmax (float or None, default None) – Maximum value for colormap normalization. If None, uses range_max if provided, otherwise uses max of in-range values.
range_min (float or None, default None) – Minimum threshold for values. Values below this will be set to range_color.
range_max (float or None, default None) – Maximum threshold for values. Values above this will be set to range_color.
range_color (tuple, default (200, 200, 200)) – Color to assign to out-of-range values, in RGB or RGBA format.
- Returns:
all_colors – Mapped colors in the specified format.
- Return type:
list of str or numpy.ndarray
- Raises:
ValueError – If output_format is not supported or cmap is invalid.
TypeError – If values is not a list or numpy array.
- clabtoolkit.colorstools.colors_to_table(colors, alpha_values=0, values=None)[source]
Convert color list to a color table. The color table will contain RGB values, alpha channel, and values or packed RGB values.
This function harmonizes the input colors to RGB format, applies alpha values, and generates a color table with the specified values. It supports both hexadecimal color strings and RGB arrays. If values are not provided, it will generate a default packed RGB value for each color.
If only the colors are provided, the function will create a color table with the RGB values, an alpha channel set to 0, and default packed RGB values. This structure is useful for creating a color table that can be used in FreeSurfer.
- Parameters:
colors (list or np.ndarray) – List of hexadecimal color strings (e.g., [‘#FF0000’, ‘#00FF00’]) or numpy array of RGB values. It can be also a list of mixture of hexadecimal strings and RGB arrays.
alpha_values (np.ndarray) – Array of alpha values for each color. If a single value is provided, it will be applied to all colors.
values (np.ndarray, optional) – Array of values corresponding to each color. If a single value is provided,
- Returns:
color_table – Color table with shape (N, 5) containing RGB values, alpha channel, and values or packed RGB values.
- Return type:
np.ndarray
- Raises:
ValueError – If colors is not a list or numpy array.
Examples
>>> # Convert hex colors to color table >>> hex_colors = ["#FF0000", "#00FF00", "#0000FF"] >>> ctab = colors2colortable(hex_colors) >>> print(f"Color table shape: {ctab.shape}")
- clabtoolkit.colorstools.visualize_colors(colors, figsize=(10, 1), label_position='below', label_rotation=45, label_size=None, spacing=0.1, aspect_ratio=0.1, background_color='white', edge_color=None)[source]
Visualize a list of color codes in a clean, professional layout with configurable display options.
- colorsList[str]
List of hexadecimal color codes to visualize (e.g., [‘#FF5733’, ‘#33FF57’])
- figsizetuple, optional
Size of the figure in inches (width, height), by default (10, 2)
- label_positionstr, optional
Position of color labels relative to color bars (‘above’ or ‘below’), by default “below”
- label_rotationint, optional
Rotation angle for labels in degrees (0-90), by default 45
- label_sizeOptional[float], optional
Font size for labels. If None, size is automatically determined based on number of colors, by default None
- spacingfloat, optional
Additional vertical space for labels (relative to bar height), by default 0.1
- aspect_ratiofloat, optional
Height/width ratio of color rectangles (0.1-1.0 recommended), by default 0.2
- background_colorstr, optional
Background color of the figure, by default “white”
- edge_colorOptional[str], optional
Color for rectangle borders. None means no borders, by default None
- None
Displays a matplotlib figure with the color visualization
- ValueError
If any color code is invalid If label_position is not ‘above’ or ‘below’
Basic usage: >>> colors = [‘#FF5733’, ‘#33FF57’, ‘#3357FF’] >>> visualize_colors(colors)
Customized visualization: >>> visualize_colors( … colors, … figsize=(12, 3), … label_position=’above’, … label_rotation=30, … background_color=’#f0f0f0’, … edge_color=’black’ … )
All hex colors will be converted to lowercase for consistency
For large numbers of colors, consider increasing figsize or decreasing label_size
Edge colors can be used to improve visibility against similar backgrounds
- class clabtoolkit.colorstools.ColorTableLoader(ctab_file)[source]
Bases:
objectClass for loading and managing color lookup tables.
- __init__(ctab_file)[source]
Initialize ColorTableLoader by loading a color lookup table from a file.
- Parameters:
ctab_file (str, Path, or dict) –
Path to the color lookup table file (.txt, .lut, or .tsv) or a dictionary containing color table data. .. attribute:: index
List of integer region codes (standard Python integers)
- type:
list of int
- Raises:
FileNotFoundError – If the specified file does not exist
ValueError – If the file format cannot be determined or is invalid
Examples
>>> # Load a FreeSurfer LUT file >>> lut_loader = ColorTableLoader('FreeSurferColorLUT.txt') >>> print(lut_loader.index[:3]) [0, 1, 2] >>> print(lut_loader.name[:3])
- static load_colortable(in_file, filter_by_name=None)[source]
Automatically detect and load a color lookup table from either LUT or TSV format.
This method intelligently determines the file format (FreeSurfer LUT or TSV) and uses the appropriate parser to load the color table data. Detection is based on file extension and/or file content analysis.
- Parameters:
- Returns:
Dictionary with the following keys: - ‘index’: List of integer region codes (standard Python integers) - ‘name’: List of region name strings - ‘color’: List of color codes (format depends on source file) - Additional keys may be present depending on the file format
- Return type:
Examples
>>> # Load a FreeSurfer LUT file >>> lut_dict = ColorTableLoader.load_colortable('FreeSurferColorLUT.txt') >>> lut_dict['index'][:3] [0, 1, 2] >>> lut_dict['name'][:3] ['Unknown', 'Left-Cerebral-Exterior', 'Left-Cerebral-White-Matter']
>>> # Load a TSV file >>> tsv_dict = ColorTableLoader.load_colortable('regions.tsv') >>> tsv_dict['index'][:3] [0, 1, 2]
>>> # Load with filtering >>> hippo_dict = ColorTableLoader.load_colortable( ... 'FreeSurferColorLUT.txt', ... filter_by_name='hippocampus' ... )
- Raises:
FileNotFoundError – If the specified file does not exist
ValueError – If the file format cannot be determined or is invalid
Notes
File format detection uses both extension and content analysis
.tsv files are assumed to be TSV format
.txt and .lut files are analyzed to determine if they are LUT or TSV format
LUT format is identified by comment lines starting with ‘#’
TSV format is identified by tab-separated columns with headers
- static read_luttable(in_file, filter_by_name=None)[source]
Read and parse a FreeSurfer Color Lookup Table (LUT) file.
This method reads a FreeSurfer color lookup table file and parses its contents into a structured dictionary containing region codes, names, and colors. The LUT file format follows FreeSurfer’s standard format where each non-comment line contains a region code, name, and RGB color values.
- Parameters:
- Returns:
Dictionary with the following keys: - ‘index’: List of integer region codes (standard Python integers) - ‘name’: List of region name strings - ‘color’: List of hex color codes (format: ‘#RRGGBB’) - ‘opacity’: List of opacity values - ‘headerlines’: List of comment lines before the R G B A header (without #)
- Return type:
Examples
>>> lut_dict = ColorTableLoader.read_luttable('FreeSurferColorLUT.txt') >>> print(f"Found {len(lut_dict['index'])} regions") Found 1234 regions
>>> lut_dict['index'][:3] [0, 1, 2] >>> lut_dict['name'][:3] ['Unknown', 'Left-Cerebral-Exterior', 'Left-Cerebral-White-Matter'] >>> lut_dict['color'][:3] ['#000000', '#4682b4', '#f5f5f5']
>>> # Filter for hippocampus regions >>> hippo_dict = ColorTableLoader.read_luttable( ... 'FreeSurferColorLUT.txt', ... filter_by_name='hippocampus' ... ) >>> print(hippo_dict['name']) ['Left-Hippocampus', 'Right-Hippocampus', ...]
>>> # Filter for multiple patterns >>> regions = ColorTableLoader.read_luttable( ... 'FreeSurferColorLUT.txt', ... filter_by_name=['hippocampus', 'amygdala'] ... )
Notes
Comment lines (starting with ‘#’) in the LUT file are ignored
Each non-comment line should have at least 5 elements: code, name, R, G, B
The returned region codes are standard Python integers, not numpy objects
Color values are converted from RGB to hexadecimal format
Filtering is case-insensitive and matches substrings
Header lines before “R G B A” are collected without the # symbol
- static read_tsvtable(in_file, filter_by_name=None)[source]
Read and parse a TSV (Tab-Separated Values) lookup table file.
This method reads a TSV file containing parcellation information and returns a dictionary with the data. The TSV file must contain at least ‘index’ and ‘name’ columns. If a ‘color’ column is present, it will be included in the returned dictionary.
- Parameters:
- Returns:
Dictionary with keys corresponding to column names in the TSV file. Must include at least: - ‘index’: List of integer region codes (standard Python integers) - ‘name’: List of region name strings May also include: - ‘color’: List of color codes if present in the TSV file - Any other columns present in the TSV file
- Return type:
- Raises:
FileNotFoundError – If the specified TSV file does not exist
ValueError – If the TSV file does not contain required ‘index’ and ‘name’ columns, is empty, or cannot be parsed
Examples
>>> tsv_dict = ColorTableLoader.read_tsvtable('regions.tsv') >>> print(f"Columns: {list(tsv_dict.keys())}") Columns: ['index', 'name', 'color', 'abbreviation']
>>> tsv_dict['index'][:3] [0, 1, 2] >>> tsv_dict['name'][:3] ['Unknown', 'Left-Cerebral-Exterior', 'Left-Cerebral-White-Matter']
>>> # Filter for specific regions >>> filtered = ColorTableLoader.read_tsvtable( ... 'regions.tsv', ... filter_by_name=['cortex', 'hippocampus'] ... )
Notes
The ‘index’ column values are converted to standard Python integers
All other columns are preserved in their original format
Filtering is case-insensitive and matches substrings
- static write_luttable(lut_df, out_file=None, boolappend=False, force=True)[source]
Write a FreeSurfer format lookup table file.
This method creates a FreeSurfer-compatible color lookup table file from region codes, names, and colors. The output follows the standard FreeSurfer LUT format with optional header lines.
- Parameters:
lut_df (pd.DataFrame or dict) – DataFrame or dictionary containing the following keys/columns: - ‘index’: List of integer region codes - ‘name’: List of region name strings - ‘color’: List of colors in RGB format (as list/array of [R, G, B] values) or hexadecimal format (as list of ‘#RRGGBB’ strings) - ‘opacity’: List of opacity values (0-1 range) - ‘headerlines’: Optional list of header lines to include at the top of the file. If the list is empty, a default header with timestamp will be generated. Default is None. - If a dictionary is provided, it must contain the same keys.
out_file (str, optional) – Output file path. If None, returns formatted lines without writing to file. Default is None.
boolappend (bool, optional) – If True, append to existing file. If False, create new file or overwrite. Default is False.
force (bool, optional) – If True, overwrite existing files without warning. If False, warn before overwriting. Default is True.
- Returns:
List of formatted LUT lines as strings
- Return type:
Examples
>>> # Create a simple LUT file >>> lut_data = { ... 'index': [0, 1, 2], ... 'name': ['Unknown', 'Left-Cerebral-Exterior', 'Left-Cerebral-White-Matter'], ... 'color': ['#000000', '#4682b4', '#f5f5f5'], ... 'opacity': [1.0, 1.0, 1.0] ... } >>> ColorTableLoader.write_luttable( ... lut_df=lut_data, ... out_file='output_lut.txt', ... boolappend=False, ... force=True ... )
Notes
Output format follows FreeSurfer LUT specification
RGB values should be in range [0, 255]
Hex colors should be in format ‘#RRGGBB’
Alpha channel is always set to 0 in output
- static write_tsvtable(tsv_df, out_file, boolappend=False, force=False)[source]
Write a TSV format lookup table file.
This method creates a tab-separated values (TSV) file from a pandas DataFrame or dictionary containing parcellation information. The data must include at least ‘index’ and ‘name’ columns/keys.
- Parameters:
tsv_df (pd.DataFrame or dict) – Data to write with index/name/color information. Must contain at least ‘index’ and ‘name’ keys/columns.
out_file (str) – Output file path for the TSV file
boolappend (bool, optional) – If True, append to existing TSV file. If False, create new file or overwrite. Default is False.
force (bool, optional) – If True, overwrite existing files without warning. If False, warn before overwriting. Default is False.
- Returns:
Path to the output TSV file
- Return type:
- Raises:
ValueError – If the input data does not contain required ‘index’ and ‘name’ keys/columns, if colors are not in hexadecimal format, or if append is requested but file doesn’t exist
Examples
>>> # Write from dictionary >>> data = { ... 'index': [1, 2, 3], ... 'name': ['region1', 'region2', 'region3'], ... 'color': ['#FF0000', '#00FF00', '#0000FF'] ... } >>> ColorTableLoader.write_tsvtable(data, 'regions.tsv', force=True) 'regions.tsv'
>>> # Write from DataFrame >>> import pandas as pd >>> df = pd.DataFrame(data) >>> ColorTableLoader.write_tsvtable(df, 'regions.tsv', force=True)
>>> # Append to existing file >>> new_data = { ... 'index': [4], ... 'name': ['region4'], ... 'color': ['#FFFF00'] ... } >>> ColorTableLoader.write_tsvtable(new_data, 'regions.tsv', boolappend=True)
Notes
Output is tab-separated with column headers
RGB colors are automatically converted to hexadecimal format
When appending, columns are matched by name; missing values are filled with empty strings
The output file includes a header row with column names
- export(out_ctab, out_format='lut', headerlines=None, append=False, overwrite=True)[source]
Export the loaded color table to specified format.
- Parameters:
Examples
>>> parcellation.export_to_file('fsl_colors.lut', out_format='fslctab') >>> parcellation.export_to_file('nilearn_colors.tsv', out_format='nilearnctab')
- export_to_fslctab(out_ctab, overwrite=True)[source]
Export the loaded color table to FSL LUT format.
- Parameters:
out_ctab (str) – Path for output FSL LUT file.
Examples
- export_to_nilearnctab(out_ctab, overwrite=False)[source]
Export the color table to nilearn-compatible format.
This function reads a color lookup table and converts it to a pandas-readable format that nilearn’s NiftiLabelsMasker can use.
- Parameters:
- Raises:
FileNotFoundError – If input_lut_path doesn’t exist or output directory doesn’t exist
FileExistsError – If output file exists and overwrite=False
ValueError – If no valid data lines are found in the input file
Examples
- export_to_lutctab(out_ctab=None, headerlines=None, append=False, overwrite=False)[source]
Export the color table to LUT format. This function writes the color table to a FreeSurfer-compatible LUT file.
- Parameters:
out_ctab (str or Path) – Path for the output LUT file. If None, returns the LUT lines as a list of strings.
headerlines (list or str, optional) – Custom header lines to include at the top of the file. If None, a default header with timestamp will be generated. Default is None.
append (bool, optional) – If True, append to existing file. If False, create new file or overwrite. Default is False.
overwrite (bool, optional) – Whether to overwrite the output file if it already exists. Default: False
- Raises:
FileNotFoundError – If output directory doesn’t exist
FileExistsError – If output file exists and overwrite=False
- export_to_tsvctab(out_ctab=None, overwrite=False)[source]
Export the color table to TSV format.
This function writes the color table to a tab-separated values (TSV) file.
- Parameters:
- Raises:
FileNotFoundError – If output directory doesn’t exist
FileExistsError – If output file exists and overwrite=False
The colorstools module centralizes colour handling across the toolkit: format conversion and validation, palette generation, colour lookup table (LUT) loading and export, and colour visualization.
Key Features
Conversion between hexadecimal, 0-255 RGB and 0-1 RGB formats
Colour validation and automatic range detection
Random and perceptually distinguishable palette generation
Mapping of numerical values to colours through matplotlib colormaps
Loading of FreeSurfer LUT and TSV colour tables
Export to FreeSurfer, FSL, nilearn and TSV formats
Colour table and palette visualization
Terminal colour codes via
bcolors
Main Classes
ColorTableLoader
Loads and manages colour lookup tables, and exports them to the formats used across neuroimaging suites.
Key Methods:
- load_colortable(): Detect and load a LUT or TSV colour table automatically
- read_luttable(): Read a FreeSurfer Color Lookup Table
- read_tsvtable(): Read a TSV lookup table
- write_luttable(): Write a FreeSurfer format lookup table
- write_tsvtable(): Write a TSV format lookup table
- export(): Export the loaded table to a specified format
- export_to_lutctab(): Export to FreeSurfer LUT format
- export_to_tsvctab(): Export to TSV format
- export_to_fslctab(): Export to FSL LUT format
- export_to_nilearnctab(): Export to nilearn-compatible format
bcolors
Terminal colour escape codes for coloured console output.
Main Functions
Format Conversion
rgb2hex(): Convert RGB values to a hexadecimal colour codehex2rgb(): Convert a hexadecimal colour code to RGBmulti_rgb2hex(): Convert an array of RGB colours to hexadecimalmulti_hex2rgb(): Convert a list of hexadecimal colours to RGBnormalize_rgb(): Convert an RGB array to the 0-1 range regardless of input formatharmonize_colors(): Convert a list of colours to a consistent formatreadjust_colors(): Wrapper aroundharmonize_colors()invert_colors(): Invert colours while preserving the input format
Validation
is_color_like(): Validate a colour, including numpy arrays and listsis_valid_hex_color(): Strict hexadecimal colour validationis_valid_rgb_255(): Check for a valid 0-255 RGB arrayis_valid_rgb_01(): Check for a valid 0-1 RGB arraydetect_rgb_range(): Detect whether an RGB array uses the 0-255 or 0-1 range
Palette Generation
create_random_colors(): Generate colours randomly or from a matplotlib colormapcreate_distinguishable_colors(): Generate maximally distinguishable colours by perceptual spacingget_predefined_distinguishable_colors(): Retrieve a predefined distinguishable paletteget_colormaps_names(): List matplotlib colormap namesvalues2colors(): Map numerical values to colours through a colormap
Colour Tables
create_lut_dictionary(): Build a LUT dictionary mapping parcel values to coloursget_colors_from_colortable(): Build per-vertex RGBA colours from parcellation labelscolors_to_table(): Convert a colour list into a colour table
Visualization
visualize_colors(): Display a list of colour codes in a labelled layoutcolortable_visualization(): Render a FreeSurfer-style colour table to PNG
Common Usage Examples
Format conversion and validation:
import clabtoolkit.colorstools as cltcolors
# Convert between formats
hex_code = cltcolors.rgb2hex(255, 128, 0)
rgb = cltcolors.hex2rgb("#ff8000")
# Batch conversion
hex_list = cltcolors.multi_rgb2hex([[255, 0, 0], [0, 255, 0]])
rgb_array = cltcolors.multi_hex2rgb(["#ff0000", "#00ff00"])
# Validate and normalize
if cltcolors.is_valid_hex_color("#ff8000"):
normalized = cltcolors.normalize_rgb([255, 128, 0])
# Detect which range an array uses
rng = cltcolors.detect_rgb_range([0.5, 0.2, 0.1])
Generating palettes:
# Maximally distinguishable colours for plotting many regions
colors = cltcolors.create_distinguishable_colors(n=20, output_format="hex")
# Random colours, optionally drawn from a colormap
colors = cltcolors.create_random_colors(n=10, output_format="hex", cmap="viridis")
# Map values onto a colormap
colors = cltcolors.values2colors(
values=[0.1, 0.5, 0.9],
cmap="jet",
output_format="hex"
)
# Preview a palette
cltcolors.visualize_colors(colors)
Loading and exporting colour tables:
from clabtoolkit.colorstools import ColorTableLoader
# Format is detected automatically for LUT and TSV inputs
loader = ColorTableLoader("/path/to/lookup_table.lut")
# Export to the format required downstream
loader.export_to_tsvctab("/path/to/output.tsv", overwrite=True)
loader.export_to_fslctab("/path/to/output_fsl.lut", overwrite=True)
loader.export_to_nilearnctab("/path/to/output_nilearn.txt", overwrite=True)
# Render the colour table as a PNG figure
cltcolors.colortable_visualization(
colortable="/path/to/lookup_table.lut",
export_path="/path/to/colortable.png"
)