ColorMap: keep RGBA values as uint8, clean up docstrings (#1722)

* keep RGBA values as uint8, clean up docstrings

* ColorMap docstring correction

* enum mapping fix 2
This commit is contained in:
Nils Nemitz 2021-04-20 15:03:44 +09:00 committed by GitHub
parent c62e51f4d8
commit a6f9a2be12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 48 deletions

View File

@ -1,9 +1,9 @@
import numpy as np
from .Qt import QtGui, QtCore
from .python2_3 import basestring
from .functions import mkColor, eq
from os import path, listdir
from collections.abc import Callable, Sequence
import warnings
_mapCache = {}
@ -193,16 +193,11 @@ class ColorMap(object):
| 1.0 -> white
The colors for intermediate values are determined by interpolating between
the two nearest colors in either RGB or HSV color space.
the two nearest colors in RGB color space.
To provide user-defined color mappings, see :class:`GradientWidget <pyqtgraph.GradientWidget>`.
"""
## color interpolation modes
RGB = 1
HSV_POS = 2
HSV_NEG = 3
## mapping modes
CLIP = 1
REPEAT = 2
@ -215,59 +210,52 @@ class ColorMap(object):
QCOLOR = 3
enumMap = {
'rgb': RGB,
# 'hsv+': HSV_POS,
# 'hsv-': HSV_NEG,
# 'clip': CLIP,
# 'repeat': REPEAT,
'clip': CLIP,
'repeat': REPEAT,
'mirror': MIRROR,
'diverging': DIVERGING,
'byte': BYTE,
'float': FLOAT,
'qcolor': QCOLOR,
}
def __init__(self, pos, color, mode=None, mapping=None): #, names=None):
def __init__(self, pos, color, mapping=CLIP, mode=None): #, names=None):
"""
=============== =================================================================
=============== =======================================================================
**Arguments:**
pos Array of positions where each color is defined
color Array of colors.
Values are interpreted via
:func:`mkColor() <pyqtgraph.mkColor>`.
mode Array of color modes (ColorMap.RGB, HSV_POS, or HSV_NEG)
indicating the color space that should be used when
interpolating between stops. Note that the last mode value is
ignored. By default, the mode is entirely RGB.
mapping Mapping mode (ColorMap.CLIP, REPEAT, MIRROR, or DIVERGING)
controlling mapping of relative index to color.
CLIP maps colors to [0.0;1.0]
mapping Mapping mode (ColorMap.CLIP, REPEAT, MIRROR or DIVERGING)
controlling mapping of relative index to color. String representations
'clip', 'repeat', 'mirror' or 'diverging' are also accepted.
CLIP maps colors to [0.0;1.0] and is the default.
REPEAT maps colors to repeating intervals [0.0;1.0];[1.0-2.0],...
MIRROR maps colors to [0.0;-1.0] and [0.0;+1.0] identically
DIVERGING maps colors to [-1.0;+1.0]
=============== =================================================================
=============== =======================================================================
"""
if mode is not None:
warnings.warn(
"'mode' argument is deprecated and does nothing.",
DeprecationWarning, stacklevel=2
)
if isinstance(mapping, str):
mapping = self.enumMap[mapping.lower()]
self.pos = np.array(pos)
order = np.argsort(self.pos)
self.pos = self.pos[order]
self.color = np.apply_along_axis(
func1d = lambda x: mkColor(x).getRgb(),
func1d = lambda x: np.uint8( mkColor(x).getRgb() ), # cast RGB integer values to uint8
axis = -1,
arr = color,
)[order]
if mode is None:
mode = np.ones(len(pos))
self.mode = mode
if mapping is None:
self.mapping_mode = self.CLIP
elif mapping == self.REPEAT:
self.mapping_mode = self.REPEAT
elif mapping == self.DIVERGING:
self.mapping_mode = self.DIVERGING
elif mapping == self.MIRROR:
self.mapping_mode = self.MIRROR
else:
self.mapping_mode = self.CLIP
self.mapping_mode = self.CLIP # default to CLIP mode
if mapping in [self.CLIP, self.REPEAT, self.DIVERGING, self.MIRROR]:
self.mapping_mode = mapping # only allow defined values
self.stopsCache = {}
def __getitem__(self, key):
@ -281,7 +269,7 @@ class ColorMap(object):
except ValueError: pass
return None
def map(self, data, mode='byte'):
def map(self, data, mode=BYTE):
"""
Return an array of colors corresponding to the values in *data*.
Data must be either a scalar position or an array (any shape) of positions.
@ -294,7 +282,7 @@ class ColorMap(object):
qcolor Values are returned as an array of QColor objects.
=========== ===============================================================
"""
if isinstance(mode, basestring):
if isinstance(mode, str):
mode = self.enumMap[mode.lower()]
if mode == self.QCOLOR:
@ -302,9 +290,6 @@ class ColorMap(object):
else:
pos, color = self.getStops(mode)
# Interpolate
# TODO: is griddata faster?
# interp = scipy.interpolate.griddata(pos, color, data)
if np.isscalar(data):
interp = np.empty((color.shape[1],), dtype=color.dtype)
else:
@ -364,7 +349,7 @@ class ColorMap(object):
def getColors(self, mode=None):
"""Return list of all color stops converted to the specified mode.
If mode is None, then no conversion is done."""
if isinstance(mode, basestring):
if isinstance(mode, str):
mode = self.enumMap[mode.lower()]
color = self.color
@ -383,11 +368,9 @@ class ColorMap(object):
if mode not in self.stopsCache:
color = self.color
if mode == self.BYTE and color.dtype.kind == 'f':
color = (color * 255).astype(np.ubyte)
color = (color*255).astype(np.ubyte)
elif mode == self.FLOAT and color.dtype.kind != 'f':
color = color.astype(float) / 255.
## to support HSV mode, we need to do a little more work..
self.stopsCache[mode] = (self.pos, color)
return self.stopsCache[mode]
@ -406,7 +389,7 @@ class ColorMap(object):
See :func:`map() <pyqtgraph.ColorMap.map>`.
=============== =============================================================================
"""
if isinstance(mode, basestring):
if isinstance(mode, str):
mode = self.enumMap[mode.lower()]
if alpha is None:

View File

@ -93,7 +93,7 @@ def test_NonUniformImage_colormap():
image = NonUniformImage(x, y, Z, border=fn.mkPen('g'))
cmap = ColorMap(pos=[0.0, 1.0], color=[(0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0)], mode='rgb')
cmap = ColorMap(pos=[0.0, 1.0], color=[(0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0)])
image.setColorMap(cmap)
viewbox.addItem(image)