renoir.color.namer

Color naming module for evocative, artist-friendly color identification.

This module provides tools for converting RGB/hex colors to memorable, evocative names like “Burnt Sienna” or “Prussian Blue” rather than technical codes. Uses perceptually accurate color matching (CIEDE2000).

class renoir.color.namer.ColorNamer(vocabulary='artist')[source]

Bases: object

Convert colors to evocative, artist-friendly names.

This class provides paint manufacturer-style color naming using perceptually accurate color matching. Supports multiple naming vocabularies from traditional artist pigments to modern design colors.

vocabulary

Currently active color vocabulary

_colors

Cached color data for current vocabulary

_lab_cache

Cache of Lab color space conversions

Example

>>> from renoir.color import ColorNamer
>>> namer = ColorNamer(vocabulary="artist")
>>> result = namer.name((255, 87, 51))
>>> print(result['name'])
'Cadmium Orange'
classmethod available_vocabularies()[source]

Get list of available color vocabularies.

Return type:

List[str]

Returns:

List of vocabulary names that can be used

Example

>>> vocabs = ColorNamer.available_vocabularies()
>>> print(vocabs)
['artist', 'resene', 'natural', 'werner', 'xkcd']
name(color, return_metadata=False)[source]

Find the closest color name for an RGB or hex color.

Uses CIEDE2000 perceptual color difference for accurate matching.

Parameters:
  • color (Union[Tuple[int, int, int], str]) – RGB tuple (R, G, B) or hex string (‘#RRGGBB’)

  • return_metadata (bool) – If True, return full metadata dictionary, otherwise just the color name (default: False)

Returns:

Color name string If return_metadata=True: Dictionary with keys:

  • name: Color name

  • hex: Hex color code

  • rgb: RGB tuple

  • distance: CIEDE2000 distance from input

  • vocabulary: Active vocabulary name

  • family: Color family (if available)

  • ci_name: Color Index name (if available)

  • description: Color description (if available)

Return type:

If return_metadata=False

Raises:

ValueError – If color format is invalid

Example

>>> namer = ColorNamer(vocabulary="artist")
>>> namer.name((255, 87, 51))
'Cadmium Orange'
>>> namer.name("#FF5733", return_metadata=True)
{'name': 'Cadmium Orange', 'hex': '#FF6103', ...}
name_palette(colors, return_metadata=False)[source]

Name multiple colors in a palette.

Parameters:
  • colors (List[Tuple[int, int, int]]) – List of RGB tuples

  • return_metadata (bool) – If True, return metadata dictionaries

Return type:

List[Union[str, Dict]]

Returns:

List of color names or metadata dictionaries

Example

>>> namer = ColorNamer()
>>> palette = [(255, 87, 51), (100, 200, 150), (50, 100, 200)]
>>> names = namer.name_palette(palette)
>>> print(names)
['Cadmium Orange', 'Mountain Meadow', 'Denim']
closest_pigment(color)[source]

Find the closest actual artist pigment (with Color Index name).

Useful for digital-to-physical color matching. Only searches colors that have Color Index names in the artist vocabulary.

Parameters:

color (Union[Tuple[int, int, int], str]) – RGB tuple or hex string

Return type:

Dict[str, any]

Returns:

Dictionary with pigment name, CI name, and color info

Example

>>> namer = ColorNamer()
>>> result = namer.closest_pigment((45, 82, 128))
>>> print(f"{result['name']} ({result['ci_name']})")
'Prussian Blue (PB27)'
set_vocabulary(vocabulary)[source]

Switch to a different color vocabulary.

Parameters:

vocabulary (str) – Name of vocabulary to switch to

Raises:

ValueError – If vocabulary is not recognized

Return type:

None

Example

>>> namer = ColorNamer(vocabulary="artist")
>>> namer.set_vocabulary("xkcd")
>>> namer.name((255, 87, 51))
'orange pink'
get_vocabulary_info()[source]

Get information about the current vocabulary.

Return type:

Dict[str, any]

Returns:

Dictionary with vocabulary metadata

Example

>>> namer = ColorNamer(vocabulary="artist")
>>> info = namer.get_vocabulary_info()
>>> print(f"{info['name']}: {info['count']} colors")
'artist: 48 colors'
translate(color_name, from_vocabulary=None, to_vocabulary='xkcd', k=3)[source]

Translate a colour name from one vocabulary to another.

Creates a “colour Rosetta Stone” by finding the perceptually closest names in the target vocabulary via CIEDE2000 matching in Lab space.

Parameters:
  • color_name (str) – Name of the colour to translate (case-insensitive)

  • from_vocabulary (Optional[str]) – Source vocabulary. If None, uses current vocabulary.

  • to_vocabulary (str) – Target vocabulary name.

  • k (int) – Number of closest matches to return (default: 3).

Returns:

  • source_name: Original colour name

  • source_vocabulary: Source vocabulary

  • source_rgb: RGB of the source colour

  • translations: List of dicts with name, rgb, hex, distance

  • target_vocabulary: Target vocabulary name

Return type:

Dictionary containing

Raises:

ValueError – If colour name not found or vocabulary is invalid.

Example

>>> namer = ColorNamer(vocabulary="werner")
>>> result = namer.translate("Gamboge Yellow", to_vocabulary="xkcd")
>>> for t in result['translations']:
...     print(f"  {t['name']} (ΔE={t['distance']:.1f})")
translate_all_vocabularies(color_name, from_vocabulary=None, k=1)[source]

Translate a colour name to all other vocabularies at once.

Parameters:
  • color_name (str) – Name of the colour to translate

  • from_vocabulary (Optional[str]) – Source vocabulary. If None, uses current.

  • k (int) – Number of matches per vocabulary (default: 1)

Return type:

Dict

Returns:

Dictionary mapping vocabulary names to translation results.

Example

>>> namer = ColorNamer(vocabulary="artist")
>>> result = namer.translate_all_vocabularies("Prussian Blue")
>>> for vocab, trans in result.items():
...     print(f"  {vocab}: {trans['translations'][0]['name']}")
historical_pigment_probability(color, year, temperature=15.0, top_k=5)[source]

Estimate probability of historical pigments for a colour at a given date.

Uses Bayesian reasoning: P(pigment|colour,date) is proportional to perceptual match (CIEDE2000) multiplied by historical availability.

Pigments with year_introduced/year_discontinued fields in the artist vocabulary are used. Pigments without date fields are assumed always available.

Parameters:
  • color (Union[Tuple[int, int, int], str]) – RGB tuple or hex string

  • year (int) – Year to evaluate pigment availability

  • temperature (float) – Softmax temperature for perceptual match (lower = stricter). Default 15.0 gives reasonable discrimination.

  • top_k (int) – Number of top pigments to return (default: 5)

Returns:

  • name: Pigment name

  • ci_name: Color Index name (if available)

  • rgb: RGB tuple

  • probability: Normalised probability (0–1)

  • ciede2000: Raw CIEDE2000 distance

  • available: Whether pigment was available at given year

Return type:

List of dicts sorted by probability, each containing

Example

>>> namer = ColorNamer()
>>> results = namer.historical_pigment_probability((0, 50, 200), year=1780)
>>> for r in results:
...     print(f"  {r['name']}: prob={r['probability']:.3f}, available={r['available']}")