diff --git a/pyqtgraph/colormap.py b/pyqtgraph/colormap.py index 88919e15..3c6c0ada 100644 --- a/pyqtgraph/colormap.py +++ b/pyqtgraph/colormap.py @@ -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 `. """ - ## 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() `. - 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() `. =============== ============================================================================= """ - if isinstance(mode, basestring): + if isinstance(mode, str): mode = self.enumMap[mode.lower()] if alpha is None: diff --git a/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py b/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py index 2b6bfedf..52b7c989 100644 --- a/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py +++ b/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py @@ -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)