polished help; streamlined from_range()

This commit is contained in:
Philip Eisenlohr 2021-11-23 17:20:07 -05:00
parent c23e9fb126
commit 3e1a6dcab7
1 changed files with 54 additions and 60 deletions

View File

@ -81,20 +81,20 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
low : numpy.ndarray of shape (3) low : iterable of float (3)
Color definition for minimum value. Color definition for minimum value.
high : numpy.ndarray of shape (3) high : iterable of float (3)
Color definition for maximum value. Color definition for maximum value.
N : int, optional
The number of color quantization levels. Defaults to 256.
name : str, optional name : str, optional
The name of the colormap. Defaults to `DAMASK colormap`. Name of the colormap. Defaults to `DAMASK colormap`.
N : int, optional
Number of color quantization levels. Defaults to 256.
model : {'rgb', 'hsv', 'hsl', 'xyz', 'lab', 'msh'} model : {'rgb', 'hsv', 'hsl', 'xyz', 'lab', 'msh'}
Colormodel used for input color definitions. Defaults to `rgb`. Colormodel used for input color definitions. Defaults to `rgb`.
The available color models are: The available color models are:
- 'rgb': R(ed) G(green) B(lue). - 'rgb': Red Green Blue.
- 'hsv': H(ue) S(aturation) V(alue). - 'hsv': Hue Saturation Value.
- 'hsl': H(ue) S(aturation) L(uminance). - 'hsl': Hue Saturation Luminance.
- 'xyz': CIE Xyz. - 'xyz': CIE Xyz.
- 'lab': CIE Lab. - 'lab': CIE Lab.
- 'msh': Msh (for perceptual uniform interpolation). - 'msh': Msh (for perceptual uniform interpolation).
@ -110,41 +110,34 @@ class Colormap(mpl.colors.ListedColormap):
>>> damask.Colormap.from_range((0,0,1),(0,0,0),'blue_to_black') >>> damask.Colormap.from_range((0,0,1),(0,0,0),'blue_to_black')
""" """
low_high = np.vstack((low,high)) toMsh = dict(
if model.lower() == 'rgb': rgb=Colormap._rgb2msh,
if np.any(low_high<0) or np.any(low_high>1): hsv=Colormap._hsv2msh,
raise ValueError(f'RGB color {low} | {high} are out of range.') hsl=Colormap._hsl2msh,
xyz=Colormap._xyz2msh,
lab=Colormap._lab2msh,
msh=lambda x:x,
)
low_,high_ = map(Colormap._rgb2msh,low_high) if model.lower() not in toMsh:
elif model.lower() == 'hsv':
if np.any(low_high<0) or np.any(low_high>[360,1,1]):
raise ValueError(f'HSV color {low} | {high} are out of range.')
low_,high_ = map(Colormap._hsv2msh,low_high)
elif model.lower() == 'hsl':
if np.any(low_high<0) or np.any(low_high>[360,1,1]):
raise ValueError(f'HSL color {low} | {high} are out of range.')
low_,high_ = map(Colormap._hsl2msh,low_high)
elif model.lower() == 'xyz':
low_,high_ = map(Colormap._xyz2msh,low_high)
elif model.lower() == 'lab':
if np.any(low_high[:,0]<0):
raise ValueError(f'CIE Lab color {low} | {high} are out of range.')
low_,high_ = map(Colormap._lab2msh,low_high)
elif model.lower() == 'msh':
low_,high_ = low_high[0],low_high[1]
else:
raise ValueError(f'Invalid color model: {model}.') raise ValueError(f'Invalid color model: {model}.')
low_high = np.vstack((low,high))
outofbounds = np.bool_(False)
if model.lower() == 'rgb':
outofbounds = np.any(low_high<0) or np.any(low_high>1)
elif model.lower() == 'hsv':
outofbounds = np.any(low_high<0) or np.any(low_high>[360,1,1])
elif model.lower() == 'hsl':
outofbounds = np.any(low_high<0) or np.any(low_high>[360,1,1])
elif model.lower() == 'lab':
outofbounds = np.any(low_high[:,0]<0)
if outofbounds:
raise ValueError(f'{model.upper()} colors {low} | {high} are out of bounds.')
low_,high_ = map(toMsh[model.lower()],low_high)
msh = map(functools.partial(Colormap._interpolate_msh,low=low_,high=high_),np.linspace(0,1,N)) msh = map(functools.partial(Colormap._interpolate_msh,low=low_,high=high_),np.linspace(0,1,N))
rgb = np.array(list(map(Colormap._msh2rgb,msh))) rgb = np.array(list(map(Colormap._msh2rgb,msh)))
@ -162,9 +155,9 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
name : str name : str
The name of the colormap. Name of the colormap.
N : int, optional N : int, optional
The number of color quantization levels. Defaults to 256. Number of color quantization levels. Defaults to 256.
This parameter is not used for matplotlib colormaps This parameter is not used for matplotlib colormaps
that are of type `ListedColormap`. that are of type `ListedColormap`.
@ -179,8 +172,8 @@ class Colormap(mpl.colors.ListedColormap):
>>> damask.Colormap.from_predefined('strain') >>> damask.Colormap.from_predefined('strain')
""" """
# matplotlib presets
try: try:
# matplotlib presets
colormap = cm.__dict__[name] colormap = cm.__dict__[name]
return Colormap(np.array(list(map(colormap,np.linspace(0,1,N))) return Colormap(np.array(list(map(colormap,np.linspace(0,1,N)))
if isinstance(colormap,mpl.colors.LinearSegmentedColormap) else if isinstance(colormap,mpl.colors.LinearSegmentedColormap) else
@ -203,8 +196,8 @@ class Colormap(mpl.colors.ListedColormap):
---------- ----------
field : numpy.array of shape (:,:) field : numpy.array of shape (:,:)
Data to be shaded. Data to be shaded.
bounds : iterable of len (2), optional bounds : iterable of float (2), optional
Colormap value range (low,high). Value range (low,high) to shade with colormap.
gap : field.dtype, optional gap : field.dtype, optional
Transparent value. NaN will always be rendered transparent. Transparent value. NaN will always be rendered transparent.
@ -243,13 +236,13 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
name : str, optional name : str, optional
The name for the reversed colormap. Name for the reversed colormap.
A name of None will be replaced by the name of the parent colormap + "_r". A name of None will be replaced by the name of the parent colormap + "_r".
Returns Returns
------- -------
damask.Colormap damask.Colormap
The reversed colormap. Reversed colormap.
Examples Examples
-------- --------
@ -268,7 +261,8 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
fname : file, str, pathlib.Path, or None fname : file, str, pathlib.Path, or None
Filename or filehandle, will be name of the colormap+extension if None. Filename or filehandle.
If None, built from colormap name and ext.
ext: str ext: str
Extension of the filename. Extension of the filename.
@ -279,7 +273,7 @@ class Colormap(mpl.colors.ListedColormap):
""" """
if fname is None: if fname is None:
return open(self.name.replace(' ','_')+'.'+ext, 'w', newline='\n') return open(self.name.replace(' ','_')+(ext if ext.startswith('.') else '.'+ext), 'w', newline='\n')
elif isinstance(fname, (str, Path)): elif isinstance(fname, (str, Path)):
return open(fname, 'w', newline='\n') return open(fname, 'w', newline='\n')
else: else:
@ -294,7 +288,7 @@ class Colormap(mpl.colors.ListedColormap):
---------- ----------
fname : file, str, or pathlib.Path, optional fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.json'. consist of the name of the colormap with extension '.json'.
""" """
colors: List = [] colors: List = []
@ -320,7 +314,7 @@ class Colormap(mpl.colors.ListedColormap):
---------- ----------
fname : file, str, or pathlib.Path, optional fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.txt'. consist of the name of the colormap with extension '.txt'.
""" """
labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3} labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3}
@ -336,7 +330,7 @@ class Colormap(mpl.colors.ListedColormap):
---------- ----------
fname : file, str, or pathlib.Path, optional fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.legend'. consist of the name of the colormap with extension '.legend'.
""" """
# ToDo: test in GOM # ToDo: test in GOM
@ -357,7 +351,7 @@ class Colormap(mpl.colors.ListedColormap):
---------- ----------
fname : file, str, or pathlib.Path, optional fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.msh'. consist of the name of the colormap with extension '.msh'.
""" """
# ToDo: test in gmsh # ToDo: test in gmsh
@ -368,7 +362,7 @@ class Colormap(mpl.colors.ListedColormap):
@staticmethod @staticmethod
def _interpolate_msh(frac, def _interpolate_msh(frac: Union[float,int],
low: np.ndarray, low: np.ndarray,
high: np.ndarray) -> np.ndarray: high: np.ndarray) -> np.ndarray:
""" """
@ -448,24 +442,24 @@ class Colormap(mpl.colors.ListedColormap):
@staticmethod @staticmethod
def _hsv2rgb(hsv: np.ndarray) -> np.ndarray: def _hsv2rgb(hsv: np.ndarray) -> np.ndarray:
"""H(ue) S(aturation) V(alue) to R(red) G(reen) B(lue).""" """Hue Saturation Value to Red Green Blue."""
return np.array(colorsys.hsv_to_rgb(hsv[0]/360.,hsv[1],hsv[2])) return np.array(colorsys.hsv_to_rgb(hsv[0]/360.,hsv[1],hsv[2]))
@staticmethod @staticmethod
def _rgb2hsv(rgb: np.ndarray) -> np.ndarray: def _rgb2hsv(rgb: np.ndarray) -> np.ndarray:
"""R(ed) G(reen) B(lue) to H(ue) S(aturation) V(alue).""" """Red Green Blue to Hue Saturation Value."""
h,s,v = colorsys.rgb_to_hsv(rgb[0],rgb[1],rgb[2]) h,s,v = colorsys.rgb_to_hsv(rgb[0],rgb[1],rgb[2])
return np.array([h*360,s,v]) return np.array([h*360,s,v])
@staticmethod @staticmethod
def _hsl2rgb(hsl: np.ndarray) -> np.ndarray: def _hsl2rgb(hsl: np.ndarray) -> np.ndarray:
"""H(ue) S(aturation) L(uminance) to R(red) G(reen) B(lue).""" """Hue Saturation Luminance to Red Green Blue."""
return np.array(colorsys.hls_to_rgb(hsl[0]/360.,hsl[2],hsl[1])) return np.array(colorsys.hls_to_rgb(hsl[0]/360.,hsl[2],hsl[1]))
@staticmethod @staticmethod
def _rgb2hsl(rgb: np.ndarray) -> np.ndarray: def _rgb2hsl(rgb: np.ndarray) -> np.ndarray:
"""R(ed) G(reen) B(lue) to H(ue) S(aturation) L(uminance).""" """Red Green Blue to Hue Saturation Luminance."""
h,l,s = colorsys.rgb_to_hls(rgb[0],rgb[1],rgb[2]) h,l,s = colorsys.rgb_to_hls(rgb[0],rgb[1],rgb[2])
return np.array([h*360,s,l]) return np.array([h*360,s,l])
@ -473,7 +467,7 @@ class Colormap(mpl.colors.ListedColormap):
@staticmethod @staticmethod
def _xyz2rgb(xyz: np.ndarray) -> np.ndarray: def _xyz2rgb(xyz: np.ndarray) -> np.ndarray:
""" """
CIE Xyz to R(ed) G(reen) B(lue). CIE Xyz to Red Green Blue.
References References
---------- ----------
@ -493,7 +487,7 @@ class Colormap(mpl.colors.ListedColormap):
@staticmethod @staticmethod
def _rgb2xyz(rgb: np.ndarray) -> np.ndarray: def _rgb2xyz(rgb: np.ndarray) -> np.ndarray:
""" """
R(ed) G(reen) B(lue) to CIE Xyz. Red Green Blue to CIE Xyz.
References References
---------- ----------