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])