#!/usr/bin/env python
"""Utilities for manipulating colors and converting between representations
as RGB hex strings, tuples of floats from 0.0 to 1.0, and tuples of ints
from 0.0 to 255.
"""
import numpy
from matplotlib.colors import colorConverter
process_black = "#222222"
[docs]def get_rgb255(inp):
"""Fetch `r, g, b` values where `r, g, b` are integers ranging from 0 to 255
Parameters
----------
inp : *RGB* or *RGBA* sequence or str
Can be color hex string, like "#007ADF", a matplotlib color letter like "r",
a matplotlib color name like "black, et c."
See :meth:`matplotlib.colors.colorConverter.to_rgb`
Returns
-------
:class:`numpy.ndarray`
Numpy array of `r, g, b` tuples where `r, g, b` take integer values from 0 to 255
"""
data = colorConverter.to_rgba_array(inp)
data = (255 * data[:, :3]).round().astype(int).ravel()
return data
[docs]def get_str_from_rgb(inp):
"""Converts RGB tuples of floats from between 0.0 and 1.0 to RGB hex strings of type #RRGGBB
Parameters
----------
input : tuple
Tuple of r, g, b values in range from 0.0 to 1.0
Returns
-------
str
RGB hex string of form '#NNNNNN'
Raises
------
ValueError if values are out of range
"""
return get_str_from_rgb255((255 * numpy.array(inp)).round().astype(int))
[docs]def get_str_from_rgb255(inp):
"""Converts RGB tuples of ints from between 0 and 255 to RGB hex strings of type `#RRGGBB`
Parameters
----------
input : tuple
Tuple of r, g, b values in range from 0 to 255
Returns
-------
str
RGB hex string of form '#NNNNNN'
Raises
------
ValueError if values are out of range
"""
err_msg = "Cannot convert malformed tuple to string. Should be (0..255, 0..255, 0..255). Is: (%s)" % ", ".join(
[str(X) for X in inp]
)
try:
assert len(inp) == 3
for x in inp:
assert x >= 0 and x <= 255
stmp = "#{:0>2X}{:0>2X}{:0>2X}".format(*inp)
assert len(stmp) == 7
return stmp
except IndexError:
raise ValueError(err_msg)
except AssertionError:
raise ValueError(err_msg)
except TypeError:
raise ValueError(err_msg)
[docs]def lighten(data, amt=0.10, is255=False):
"""Lighten a vector of colors by fraction `amt` of remaining possible intensity.
New colors are calculated as::
>>> new_colors = data + amt*(1.0 - data)
>>> new_colors[:, -1] = 1 # keep all alpha at 1.0
Parameters
----------
data : matplotlib colorspec or sequence of colorspecs
input color(s)
amt : float, optional
Percentage by which to lighten `r`, `g`, and `b`. `a` remains unchanged
(Default: 0.10)
is255 : bool, optional
If `True`, rgb values in `data` are assumed to be tween 0 and 255
rather than 0.0 and 1.0. In this case, return values will also
be between 0 and 255.
Returns
-------
numpy.ndarray
Lightened version of data
"""
data = colorConverter.to_rgba_array(data)
new_colors = data + amt * (1.0 - data)
if is255:
new_colors = (255 * new_colors).round()
new_colors[:, -1] = data[:, -1]
return new_colors
[docs]def darken(data, amt=0.10, is255=False):
"""Darken a vector of colors by fraction `amt` of current intensity.
Parameters
----------
data : matplotlib colorspec or sequence of colorspecs
input color(s)
amt : float, optional
Percentage by which to darken `r`, `g`, and `b`. `a` remains unchanged
(Default: 0.10)
Returns
-------
numpy.ndarray
Lightened version of data
"""
data = colorConverter.to_rgba_array(data)
new_colors = (1.0 - amt) * data
if is255:
new_colors = (255 * new_colors).round()
new_colors[:, -1] = data[:, -1]
return new_colors