Source code for optimeed.visualize.graphs.colormap_pyqtgraph

from .pyqtgraph import ColorMap
import collections
from optimeed.core import printIfShown, SHOW_INFO
try:
    from matplotlib import cm
    has_matplotlib = True
except ImportError:
    has_matplotlib = False
    printIfShown("Matplotlib library not found -> specific 3D colormap has been deactivated", SHOW_INFO)
import numpy as np

try:
    sequence = collections.Sequence
except AttributeError:
    sequence = collections.abc.Sequence


[docs]def matplotlib_colormap_to_pg_colormap(colormap_name, n_ticks=16): pos, rgba_colors = zip(*cmapToColormap(getattr(cm, colormap_name), n_ticks)) pgColormap = ColorMap(pos, rgba_colors) return pgColormap
[docs]def cmapToColormap(cmap, nTicks=16): """Converts a Matplotlib cmap to pyqtgraphs colormaps. No dependency on matplotlib. Author: Sebastian Hoefer :param cmap: Cmap object. Imported from matplotlib.cm. :param nTicks: Number of ticks to create when dict of functions is used. Otherwise unused. :return: """ rgb_list = list() # Case #1: a dictionary with 'red'/'green'/'blue' values as list of ranges (e.g. 'jet') # The parameter 'cmap' is a 'matplotlib.colors.LinearSegmentedColormap' instance ... if hasattr(cmap, '_segmentdata'): colordata = getattr(cmap, '_segmentdata') if ('red' in colordata) and isinstance(colordata['red'], sequence): # collect the color ranges from all channels into one dict to get unique indices posDict = {} for idx, channel in enumerate(('red', 'green', 'blue')): for colorRange in colordata[channel]: posDict.setdefault(colorRange[0], [-1, -1, -1])[idx] = colorRange[2] indexList = list(posDict.keys()) indexList.sort() # interpolate missing values (== -1) for channel in range(3): # R,G,B startIdx = indexList[0] emptyIdx = [] for curIdx in indexList: if posDict[curIdx][channel] == -1: emptyIdx.append(curIdx) elif curIdx != indexList[0]: for eIdx in emptyIdx: rPos = (eIdx - startIdx) / (curIdx - startIdx) vStart = posDict[startIdx][channel] vRange = (posDict[curIdx][channel] - posDict[startIdx][channel]) posDict[eIdx][channel] = rPos * vRange + vStart startIdx = curIdx del emptyIdx[:] for channel in range(3): # R,G,B for curIdx in indexList: posDict[curIdx][channel] *= 255 rgb_list = [[i, posDict[i]] for i in indexList] # Case #2: a dictionary with 'red'/'green'/'blue' values as functions (e.g. 'gnuplot') elif ('red' in colordata) and isinstance(colordata['red'], collections.Callable): indices = np.linspace(0., 1., nTicks) luts = [np.clip(np.array(colordata[rgb](indices), dtype=np.float), 0, 1) * 255 for rgb in ('red', 'green', 'blue')] rgb_list = zip(indices, list(zip(*luts))) # If the parameter 'cmap' is a 'matplotlib.colors.ListedColormap' instance, with the attributes 'colors' and 'N' elif hasattr(cmap, 'colors') and hasattr(cmap, 'N'): colordata = getattr(cmap, 'colors') # Case #3: a list with RGB values (e.g. 'seismic') if len(colordata[0]) == 3: indices = np.linspace(0., 1., len(colordata)) scaledRgbTuples = [(rgbTuple[0] * 255, rgbTuple[1] * 255, rgbTuple[2] * 255) for rgbTuple in colordata] rgb_list = zip(indices, scaledRgbTuples) # Case #4: a list of tuples with positions and RGB-values (e.g. 'terrain') # -> this section is probably not needed anymore!? elif len(colordata[0]) == 2: rgb_list = [(idx, (vals[0] * 255, vals[1] * 255, vals[2] * 255)) for idx, vals in colordata] # Case #X: unknown format or datatype was the wrong object type else: raise ValueError("[cmapToColormap] Unknown cmap format or not a cmap!") # Convert the RGB float values to RGBA integer values return list([(pos, (int(r), int(g), int(b), 255)) for pos, (r, g, b) in rgb_list])