Colors & Palettes

This tutorial covers:

  • RGB class and color constants (wolfhece.color_constants)

  • wolfpaletteModel — headless color palette based on matplotlib’s LinearSegmentedColormap

  • wolfpalette — GUI variant (requires wxPython)

NotewolfpaletteModel works without wxPython. When wx is unavailable, wolfpalette is automatically aliased to wolfpaletteModel.

[2]:
from wolfhece.color_constants import RGB, Colors
from wolfhece.PyPalette import wolfpaletteModel
import numpy as np

RGB class — color manipulation

RGB is a named tuple (red, green, blue) with conversion helpers.

[3]:
# Create colors
red = RGB(255, 0, 0)
blue = RGB.from_hexa('#0000FF')
green = RGB.from_int(0x00FF00)

print(f"Red   : {red} -> hex={red.hexa_format()}, int={red.int_format}")
print(f"Blue  : {blue} -> 0-1 tuple={blue.to_tuple_0_to_1()}")
print(f"Green : {green} -> list={green.to_list()}")
Red   : RGB(red=255, green=0, blue=0) -> hex=#FF0000, int=16711680
Blue  : RGB(red=0, green=0, blue=255) -> 0-1 tuple=(0.0, 0.0, 1.0)
Green : RGB(red=0, green=255, blue=0) -> list=[0, 255, 0]
[ ]:
# Browse named constants
# 'Colors.named_colors' is an OrderedDict: name -> RGB instance
print(f"Available colors: {len(Colors.named_colors)}")
print(f"First 10: {list(Colors.named_colors.keys())[:10]}")

# Access a named color
coral = Colors.named_colors['coral']
print(f"CORAL = {coral}")
Available colors: 552
First 10: ['aliceblue', 'antiquewhite', 'antiquewhite1', 'antiquewhite2', 'antiquewhite3', 'antiquewhite4', 'aqua', 'aquamarine1', 'aquamarine2', 'aquamarine3']
CORAL = RGB(red=255, green=127, blue=80)

wolfpaletteModel — creating a palette

A palette maps floating-point values to RGBA colors. It extends LinearSegmentedColormap from matplotlib.

[7]:
pal = wolfpaletteModel()

# Define values and associated colors
values = [0.0, 0.5, 1.0, 2.0, 5.0]
pal_colors = [
    (0, 0, 255, 255),    # blue
    (0, 255, 255, 255),  # cyan
    (0, 255, 0, 255),    # green
    (255, 255, 0, 255),  # yellow
    (255, 0, 0, 255),    # red
]

pal.set_values_colors(values, pal_colors)
print(f"Palette entries : {pal.nb}")
print(f"Value range     : [{pal.values[0]}, {pal.values[-1]}]")
Palette entries : 5
Value range     : [0.0, 5.0]
[8]:
# Lookup a single color
rgba = pal.get_rgba_oneval(1.5)
print(f"Color at 1.5 : {rgba}")

# Lookup colors for a 2D array
data = np.linspace(0, 5, 20).reshape(4, 5)
rgba_array = pal.get_rgba(data)
print(f"Output shape : {rgba_array.shape}  (rows x cols x RGBA)")
Color at 1.5 : (np.uint8(127), np.uint8(255), np.uint8(0), np.uint8(255))
Output shape : (4, 5, 4)  (rows x cols x RGBA)

Visualizing a palette with matplotlib

[9]:
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6, 1))
gradient = np.linspace(0, 5, 256).reshape(1, -1)
ax.imshow(gradient, aspect='auto', cmap=pal, vmin=0, vmax=5)
ax.set_yticks([])
ax.set_xlabel('Value')
ax.set_title('Custom wolfpaletteModel')
plt.tight_layout()
plt.show()
../_images/tutorials_colors_palettes_9_0.png

Reading / saving .pal files

[10]:
import tempfile
from pathlib import Path

tmpdir = Path(tempfile.mkdtemp())
pal_file = tmpdir / 'demo.pal'

# Save
pal.savefile(str(pal_file))
print(f"Saved to {pal_file}")

# Reload
pal2 = wolfpaletteModel()
pal2.readfile(str(pal_file))
print(f"Reloaded: {pal2.nb} entries, range [{pal2.values[0]}, {pal2.values[-1]}]")
Saved to C:\Users\pierre\AppData\Local\Temp\tmpfhwbsd2m\demo.pal
Reloaded: 5 entries, range [0.0, 5.0]

Built-in default palettes

[11]:
pal_gray = wolfpaletteModel()
pal_gray.defaultgray()
print(f"Gray palette: {pal_gray.nb} entries")

pal16 = wolfpaletteModel()
pal16.default16()
print(f"Default16 palette: {pal16.nb} entries")
Gray palette: 3 entries
Default16 palette: 16 entries
[ ]:
# list all default palettes
# enumerate all routines begin with 'default'
for attr in dir(wolfpaletteModel):
    if attr.startswith('default'):
        print(attr)
default16
default_difference3
defaultblue
defaultblue3
defaultblue_minmax
defaultgray
defaultgray_minmax
defaultred_minmax

Summary

Class

Purpose

wx required?

RGB

Named tuple with format converters (hex, int, 0-1)

No

colors

Dictionary of ~1300 named RGB constants

No

wolfpaletteModel

Color palette (value → RGBA), matplotlib-compatible

No

wolfpalette

Adds wx dialogs for interactive editing

Yes