Skip to content

Colormaps

qim3d.viz.colormaps.qim module-attribute

qim = from_list('qim', [(0.6, 0.0, 0.0), (1.0, 0.6, 0.0)])

Defines colormap in QIM logo colors. Can be accessed as module attribute or easily by cmap = 'qim'

Example

import qim3d

display(qim3d.viz.colormaps.qim)
colormap objects

qim3d.viz.colormaps.segmentation

segmentation(
    n_labels,
    style='bright',
    first_color_background=True,
    last_color_background=False,
    background_color=(0.0, 0.0, 0.0),
    min_dist=0.5,
    seed=19,
)

Creates a randomized matplotlib colormap optimized for visualizing segmentation masks.

Generates a set of distinct colors to differentiate between multiple labels or objects in a volume. It supports various color palettes and allows specific control over background colors to ensure clear separation between classes.

Key Features:

  • Distinct Palettes: Choose from 'bright', 'soft', 'earth', or 'ocean' styles.
  • Contrast Control: Ensure neighboring labels are distinguishable with the min_dist parameter.
  • Background Handling: Explicitly set background colors (black/white) to transparency or neutral tones.

Parameters:

Name Type Description Default
n_labels int

Total number of distinct labels or classes.

required
style str

The color theme of the map.

  • 'bright': High saturation colors for maximum contrast.
  • 'soft': Pastel tones for a gentler visualization.
  • 'earth': Nature-inspired tones (greens, browns).
  • 'ocean': Cool tones (blues, purples).
'bright'
first_color_background bool

If True, sets the first color (index 0) to background_color.

True
last_color_background bool

If True, sets the last color to background_color.

False
background_color tuple or str

The RGB tuple or string ('black', 'white') for the background.

(0.0, 0.0, 0.0)
min_dist float

Minimum perceptual distance between adjacent colors in the map. Higher values reduce the chance of similar colors appearing next to each other.

0.5
seed int

Seed for the random number generator to ensure reproducibility.

19

Returns:

Name Type Description
color_map LinearSegmentedColormap

The generated matplotlib colormap object.

Tip

It can be easily used when calling visualization functions as:

qim3d.viz.slices_grid(segmented_volume, color_map = 'objects')
which automatically detects the number of unique classes and creates the colormap object with default arguments.

Tip

The min_dist parameter can be used to control the distance between neighboring colors. colormap objects mind_dist

Example

import qim3d

cmap_bright = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'bright', first_color_background=True, background_color="black", min_dist=0.7)
cmap_soft = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'soft', first_color_background=True, background_color="black", min_dist=0.2)
cmap_earth = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'earth', first_color_background=True, background_color="black", min_dist=0.8)
cmap_ocean = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'ocean', first_color_background=True, background_color="black", min_dist=0.9)

display(cmap_bright)
display(cmap_soft)
display(cmap_earth)
display(cmap_ocean)
colormap objects

import qim3d

vol = qim3d.examples.cement_128x128x128
binary = qim3d.filters.gaussian(vol, sigma = 2) < 60
labeled_volume, n_labels = qim3d.segmentation.watershed(binary)

color_map = qim3d.viz.colormaps.segmentation(n_labels, style = 'bright')
qim3d.viz.slicer(labeled_volume, slice_axis = 1, color_map=color_map)
colormap objects

Source code in qim3d/viz/colormaps/_segmentation.py
def segmentation(
    n_labels: int,
    style: str = 'bright',
    first_color_background: bool = True,
    last_color_background: bool = False,
    background_color: Union[Tuple[float, float, float], str] = (0.0, 0.0, 0.0),
    min_dist: int = 0.5,
    seed: int = 19,
) -> LinearSegmentedColormap:
    """
    Creates a randomized matplotlib colormap optimized for visualizing segmentation masks.

    Generates a set of distinct colors to differentiate between multiple labels or objects in a volume. It supports various color palettes and allows specific control over background colors to ensure clear separation between classes.

    **Key Features:**

    * **Distinct Palettes:** Choose from 'bright', 'soft', 'earth', or 'ocean' styles.
    * **Contrast Control:** Ensure neighboring labels are distinguishable with the `min_dist` parameter.
    * **Background Handling:** Explicitly set background colors (black/white) to transparency or neutral tones.

    Args:
        n_labels (int): Total number of distinct labels or classes.
        style (str, optional): The color theme of the map.

            * `'bright'`: High saturation colors for maximum contrast.
            * `'soft'`: Pastel tones for a gentler visualization.
            * `'earth'`: Nature-inspired tones (greens, browns).
            * `'ocean'`: Cool tones (blues, purples).

        first_color_background (bool, optional): If `True`, sets the first color (index 0) to `background_color`.
        last_color_background (bool, optional): If `True`, sets the last color to `background_color`.
        background_color (tuple or str, optional): The RGB tuple or string ('black', 'white') for the background.
        min_dist (float, optional): Minimum perceptual distance between adjacent colors in the map. Higher values reduce the chance of similar colors appearing next to each other.
        seed (int, optional): Seed for the random number generator to ensure reproducibility.

    Returns:
        color_map (matplotlib.colors.LinearSegmentedColormap):
            The generated matplotlib colormap object.

    Tip:
        It can be easily used when calling visualization functions as:
        ```python
        qim3d.viz.slices_grid(segmented_volume, color_map = 'objects')
        ```
        which automatically detects the number of unique classes and creates the colormap object with default arguments.

    Tip:
        The `min_dist` parameter can be used to control the distance between neighboring colors.
        ![colormap objects mind_dist](../../assets/screenshots/viz-colormaps-min_dist.gif)

    Example:
        ```python
        import qim3d

        cmap_bright = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'bright', first_color_background=True, background_color="black", min_dist=0.7)
        cmap_soft = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'soft', first_color_background=True, background_color="black", min_dist=0.2)
        cmap_earth = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'earth', first_color_background=True, background_color="black", min_dist=0.8)
        cmap_ocean = qim3d.viz.colormaps.segmentation(n_labels=100, style = 'ocean', first_color_background=True, background_color="black", min_dist=0.9)

        display(cmap_bright)
        display(cmap_soft)
        display(cmap_earth)
        display(cmap_ocean)
        ```
        ![colormap objects](../../assets/screenshots/viz-colormaps-objects-all.png)

        ```python
        import qim3d

        vol = qim3d.examples.cement_128x128x128
        binary = qim3d.filters.gaussian(vol, sigma = 2) < 60
        labeled_volume, n_labels = qim3d.segmentation.watershed(binary)

        color_map = qim3d.viz.colormaps.segmentation(n_labels, style = 'bright')
        qim3d.viz.slicer(labeled_volume, slice_axis = 1, color_map=color_map)
        ```
        ![colormap objects](../../assets/screenshots/viz-colormaps-objects.gif)
    """
    from skimage import color

    # Check style
    if style not in ('bright', 'soft', 'earth', 'ocean'):
        raise ValueError(
            f'Please choose "bright", "soft", "earth" or "ocean" for style in qim3dCmap not "{style}"'
        )

    # Translate strings to background color
    color_dict = {'black': (0.0, 0.0, 0.0), 'white': (1.0, 1.0, 1.0)}
    if not isinstance(background_color, tuple):
        try:
            background_color = color_dict[background_color]
        except KeyError:
            raise ValueError(
                f'Invalid color name "{background_color}". Please choose from {list(color_dict.keys())}.'
            )

    # Add one to n_labels to include the background color
    n_labels += 1

    # Create a new random generator, to locally set seed
    rng = np.random.default_rng(seed)

    # Generate color map for bright colors, based on hsv
    if style == 'bright':
        randHSVcolors = [
            (
                rng.uniform(low=0.0, high=1),
                rng.uniform(low=0.4, high=1),
                rng.uniform(low=0.9, high=1),
            )
            for i in range(n_labels)
        ]

        # Convert HSV list to RGB
        randRGBcolors = []
        for HSVcolor in randHSVcolors:
            randRGBcolors.append(
                colorsys.hsv_to_rgb(HSVcolor[0], HSVcolor[1], HSVcolor[2])
            )

    # Generate soft pastel colors, by limiting the RGB spectrum
    if style == 'soft':
        low = 0.6
        high = 0.95
        randRGBcolors = [
            (
                rng.uniform(low=low, high=high),
                rng.uniform(low=low, high=high),
                rng.uniform(low=low, high=high),
            )
            for i in range(n_labels)
        ]

    # Generate color map for earthy colors, based on LAB
    if style == 'earth':
        randLABColors = [
            (
                rng.uniform(low=25, high=110),
                rng.uniform(low=-120, high=70),
                rng.uniform(low=-70, high=70),
            )
            for i in range(n_labels)
        ]

        # Convert LAB list to RGB
        randRGBcolors = []
        for LabColor in randLABColors:
            randRGBcolors.append(color.lab2rgb([[LabColor]])[0][0].tolist())

    # Generate color map for ocean colors, based on LAB
    if style == 'ocean':
        randLABColors = [
            (
                rng.uniform(low=0, high=110),
                rng.uniform(low=-128, high=160),
                rng.uniform(low=-128, high=0),
            )
            for i in range(n_labels)
        ]

        # Convert LAB list to RGB
        randRGBcolors = []
        for LabColor in randLABColors:
            randRGBcolors.append(color.lab2rgb([[LabColor]])[0][0].tolist())

    # Re-arrange colors to have a minimum distance between neighboring colors
    randRGBcolors = rearrange_colors(randRGBcolors, min_dist)

    # Set first and last color to background
    if first_color_background:
        randRGBcolors[0] = background_color

    if last_color_background:
        randRGBcolors[-1] = background_color

    # Create colormap
    objects = LinearSegmentedColormap.from_list('objects', randRGBcolors, N=n_labels)

    return objects