Source code for ccpn.util.Colour

"""Module Documentation here

"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (https://www.ccpn.ac.uk) 2014 - 2022"
__credits__ = ("Ed Brooksbank, Joanna Fox, Victoria A Higman, Luca Mureddu, Eliza Płoskoń",
               "Timothy J Ragan, Brian O Smith, Gary S Thompson & Geerten W Vuister")
__licence__ = ("CCPN licence. See https://ccpn.ac.uk/software/licensing/")
__reference__ = ("Skinner, S.P., Fogh, R.H., Boucher, W., Ragan, T.J., Mureddu, L.G., & Vuister, G.W.",
                 "CcpNmr AnalysisAssign: a flexible platform for integrated NMR analysis",
                 "J.Biomol.Nmr (2016), 66, 111-124, http://doi.org/10.1007/s10858-016-0060-y")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: Ed Brooksbank $"
__dateModified__ = "$dateModified: 2022-03-11 18:38:07 +0000 (Fri, March 11, 2022) $"
__version__ = "$Revision: 3.1.0 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2017-04-07 10:28:41 +0000 (Fri, April 07, 2017) $"
#=========================================================================================
# Start of code
#=========================================================================================

"""Color specification"""

import numpy as np
from collections import OrderedDict
from PyQt5 import QtGui, QtCore
from ccpn.ui.gui.widgets.Font import getFontHeight
from ccpn.ui.gui.widgets.Icon import Icon


def _ccpnHex(val):
    """Generate hex value with padded leading zeroes
    """
    val = '{0:#0{1}x}'.format(int(val), 4)
    return '0x' + val[2:].upper()


[docs]def rgbaToHex(r, g, b, a=255): return '#' + ''.join([_ccpnHex(x)[2:] for x in (r, g, b, a)])
[docs]def rgbToHex(r, g, b): return '#' + ''.join([_ccpnHex(x)[2:] for x in (r, g, b)])
[docs]def rgbaRatioToHex(r, g, b, a=1.0): return '#' + ''.join([_ccpnHex(x)[2:] for x in (int(255.0 * r), int(255.0 * g), int(255.0 * b), int(255.0 * a))])
[docs]def rgbRatioToHex(r, g, b): return '#' + ''.join([_ccpnHex(x)[2:] for x in (int(255.0 * r), int(255.0 * g), int(255.0 * b))])
[docs]def hexToRgb(hx): if not hx: return hx = hx.lstrip('#') lv = len(hx) return tuple(int(hx[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
[docs]def hexToRgbRatio(hx): if not hx: return hx = hx.lstrip('#') lv = len(hx) return tuple(float(int(hx[i:i + lv // 3], 16)) / 255 for i in range(0, lv, lv // 3))
[docs]def hexToRgba(hx, transparency=1.0): if hx is None: return hx = hx.lstrip('#') lv = len(hx) cols = [int(hx[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)] cols.append(transparency) return tuple(cols)
[docs]def hexToRgbaArray(array, transparency=1.0): cc = [] for hx in array: cc.append(hexToRgba(hx, transparency)) return np.array(cc)
# sRGB luminance(Y) values rY = 0.212655 gY = 0.715158 bY = 0.072187 COLOUR_LIGHT_THRESHOLD = 80 COLOUR_DARK_THRESHOLD = 190 #(256 - COLOUR_LIGHT_THRESHOLD) COLOUR_THRESHOLD = 40 # Inverse of sRGB "gamma" function. (approx 2.2)
[docs]def inv_gam_sRGB(ic): c = ic / 255.0 if (c <= 0.04045): return c / 12.92 else: return pow(((c + 0.055) / (1.055)), 1.6)
# sRGB "gamma" function (approx 2.2)
[docs]def gam_sRGB(v): if (v <= 0.0031308): v *= 12.92 else: v = 1.055 * pow(v, 0.625) - 0.055 return int(v * 255)
# GRAY VALUE ("brightness")
[docs]def gray(r, g, b, a=1.0): return gam_sRGB( rY * inv_gam_sRGB(r) + gY * inv_gam_sRGB(g) + bY * inv_gam_sRGB(b) )
COLORMATRIX256CONST = [16.0, 128.0, 128.0] COLORMATRIX256 = [[65.738, 129.057, 25.064], [-37.945, -74.494, 112.439], [112.439, -94.154, -18.285]] COLORMATRIX256INVCONST = [-222.921, 135.576, -276.836] COLORMATRIX256INV = [[298.082, 0.0, 408.583], [298.082, -100.291, -208.120], [298.082, 516.412, 0.0]] # Y = 0.299 R + 0.587 G + 0.114 B # Cb = - 0.1687 R - 0.3313 G + 0.5 B + 128 # Cr = 0.5 R - 0.4187 G - 0.0813 B + 128 COLORMATRIXJPEGCONST = [0, 128, 128] COLORMATRIXJPEG = [[0.299, 0.587, 0.114], [-0.168736, -0.331264, 0.5], [0.5, -0.418688, -0.081312]] # R = Y + 1.402 (Cr-128) # G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128) # B = Y + 1.772 (Cb-128) COLORMATRIXJPEGINVCONST = [0, 0, 0] COLORMATRIXJPEGINVOFFSET = [0, -128, -128] COLORMATRIXJPEGINV = [[1.0, 0.0, 1.402], [1.0, -0.344136, -0.714136], [1.0, 1.772, 0.0]]
[docs]def colourNameNoSpace(name): """remove spaces from the colourname """ return name # currently no effect until sorted
# return ''.join(name.split())
[docs]def colourNameWithSpace(name): """insert spaces into the colourname """ # list of all possible words that are in the colour names nounList = ['dark', 'dim', 'medium', 'light', 'pale', 'white', 'rosy', 'indian', 'misty', 'red', 'orange', 'burly', 'antique', 'navajo', 'blanched', 'papaya', 'floral', 'lemon', 'olive', 'yellow', 'green', 'lawn', 'sea', 'forest', 'lime', 'spring', 'slate', 'cadet', 'powder', 'sky', 'steel', 'royal', 'ghost', 'midnight', 'navy', 'rebecca', 'blue', 'violet', 'deep', 'hot', 'lavender', 'cornflower', 'dodger', 'alice', 'sandy', 'saddle' ] subsetNouns = ['goldenrod', 'golden', 'old'] # insert spaces after found nouns colName = name for noun in nounList: if noun in colName: colName = colName.replace(noun, noun + ' ') # check for nouns that also contain shorter nouns for noun in subsetNouns: if noun in colName: colName = colName.replace(noun, noun + ' ') break # return the new name without trailing spaces, too many spaces return " ".join(colName.split())
[docs]def invertRGBLuma(r, g, b): """Invert the rgb colour using the ycbcr method by inverting the luma rgb input r, g, b in range 0-255 """ # rgbprimeIn = [gam_sRGB(r/255.0),gam_sRGB(g/255.0),gam_sRGB(b/255.0)] rgbprimeIn = [r, g, b] # rgbprimeIn r, g, b in range 0-255 cie = np.dot(COLORMATRIXJPEG, rgbprimeIn) ycbcr = np.add(cie, COLORMATRIXJPEGCONST) ycbcr = np.clip(ycbcr, [0, 0, 0], [255, 255, 255]) # invert the luma - reverse y ycbcr[0] = 255 - ycbcr[0] ycbcr = np.add(ycbcr, COLORMATRIXJPEGINVOFFSET) rgbPrimeOut = np.dot(COLORMATRIXJPEGINV, ycbcr) # rgbPrimeOut = np.add(rgbPrimeOut, COLORMATRIXJPEGINVCONST) / 256 # return tuple([255*inv_gam_sRGB(col) for col in rgbPrimeOut]) # clip the colours rgbPrimeOut = np.clip(rgbPrimeOut, [0, 0, 0], [255, 255, 255]) return tuple([float(col) for col in rgbPrimeOut])
[docs]def invertRGBHue(r, g, b): """Invert the rgb colour using the ycbcr method by finding the opposite hue rgb input r, g, b in range 0-255 """ # rgbprimeIn = [gam_sRGB(r/255.0),gam_sRGB(g/255.0),gam_sRGB(b/255.0)] rgbprimeIn = [r, g, b] # rgbprimeIn r, g, b in range 0-255 cie = np.dot(COLORMATRIXJPEG, rgbprimeIn) ycbcr = np.add(cie, COLORMATRIXJPEGCONST) ycbcr = np.clip(ycbcr, [0, 0, 0], [255, 255, 255]) # get opposite hue - reverse cb and cr ycbcr[1] = 255 - ycbcr[1] ycbcr[2] = 255 - ycbcr[2] ycbcr = np.add(ycbcr, COLORMATRIXJPEGINVOFFSET) rgbPrimeOut = np.dot(COLORMATRIXJPEGINV, ycbcr) # rgbPrimeOut = np.add(rgbPrimeOut, COLORMATRIXJPEGINVCONST) / 256 # return tuple([255*inv_gam_sRGB(col) for col in rgbPrimeOut]) # clip the colours rgbPrimeOut = np.clip(rgbPrimeOut, [0, 0, 0], [255, 255, 255]) return tuple([float(col) for col in rgbPrimeOut])
def _getRandomColours(numberOfColors): import random return ["#" + ''.join([random.choice('0123456789ABCDEF') for j in range(6)]) for i in range(numberOfColors)] ERRORCOLOUR = '#FF0000' colourNameToHexDict = { 'red' : '#ff0000', 'green' : '#00ff00', 'blue' : '#0000ff', 'yellow' : '#ffff00', 'magenta': '#ff00ff', 'cyan' : '#00ffff', } # small set of colours shortSpectrumColours = OrderedDict([('#cb1400', 'red'), ('#860700', 'dark red'), ('#933355', 'burgundy'), ('#947676', 'bazaar'), ('#d231cb', 'pink'), ('#df2950', 'pastel pink'), ('#ff8eff', 'light pink'), ('#f9609c', 'mid pink'), ('#d24c23', 'dark orange'), ('#fe6c11', 'orange'), ('#ff932e', 'light pastel orange'), ('#ecfc00', 'yellow'), ('#ffff5a', 'light yellow'), ('#50ae56', 'mid green'), ('#3fe945', 'light green'), ('#097a27', 'pastel green'), ('#064a1a', 'dark green'), ('#80ff00', 'chartreuse'), ('#1530ff', 'blue'), ('#1020aa', 'dark blue'), ('#4080ff', 'light blue'), ('#318290', 'pastel blue'), ('#2d5175', 'mid blue'), ('#4f9caa', 'light pastel blue'), ('#957eff', 'heliotrope'), ('#2f2373', 'dark purple'), ('#5846d6', 'purple'), ('#7866f8', 'light purple'), ('#d8e1cf', 'light seashell'), ('#3a4e5c', 'dark grey'), ('#7a7a7a', 'mid grey'), ('#b0b0b0', 'light grey'), ('#ffffff', 'white'), ('#000000', 'black')]) # set of colours for spectra on light background darkDefaultSpectrumColours = OrderedDict([('#008080', 'teal'), ('#DA70D6', 'orchid'), ('#800080', 'purple'), ('#808000', 'olive'), ('#1E90FF', 'dodgerblue'), ('#FFA500', 'orange'), ('#FF0000', 'red'), ('#4682B4', 'steelblue'), ('#008000', 'green'), ('#8A2BE2', 'blueviolet'), ('#800000', 'maroon'), ('#00CED1', 'darkturquoise'), ('#000080', 'navy'), ('#FF4500', 'orangered'), ('#FF1493', 'deeppink'), ('#32CD32', 'limegreen'), ]) # set of colours for spectra on dark background lightDefaultSpectrumColours = OrderedDict([('#6B8E23', 'olivedrab'), ('#DA70D6', 'orchid'), ('#8A2BE2', 'blueviolet'), ('#808000', 'olive'), ('#1E90FF', 'dodgerblue'), ('#FFA500', 'orange'), ('#FF0000', 'red'), ('#4682B4', 'steelblue'), ('#7FFF00', 'chartreuse'), ('#9932CC', 'darkorchid'), ('#A0522D', 'sienna'), ('#00CED1', 'darkturquoise'), ('#00FFFF', 'cyan'), ('#FFFF00', 'yellow'), ('#FF1493', 'deeppink'), ('#32CD32', 'limegreen'), ]) # set of colours that have higher saturation + new CCPN colours brightColours = OrderedDict([('#000000', 'black'), ('#696969', 'dimgray'), ('#696969', 'dimgrey'), ('#808080', 'gray'), ('#808080', 'grey'), ('#A9A9A9', 'darkgray'), ('#A9A9A9', 'darkgrey'), ('#C0C0C0', 'silver'), ('#D3D3D3', 'lightgray'), ('#D3D3D3', 'lightgrey'), ('#DCDCDC', 'gainsboro'), ('#F5F5F5', 'whitesmoke'), ('#FFFFFF', 'white'), ('#F08080', 'lightcoral'), ('#CD5C5C', 'indianred'), ('#A52A2A', 'brown'), ('#B22222', 'firebrick'), ('#800000', 'maroon'), ('#8B0000', 'darkred'), ('#FF0000', 'red'), ('#FA8072', 'salmon'), ('#FF6347', 'tomato'), ('#E9967A', 'darksalmon'), ('#FF7F50', 'coral'), ('#FF4500', 'orangered'), ('#FFA07A', 'lightsalmon'), ('#A0522D', 'sienna'), ('#D2691E', 'chocolate'), ('#8B4513', 'saddlebrown'), ('#F4A460', 'sandybrown'), ('#CD853F', 'peru'), ('#FF8C00', 'darkorange'), ('#DEB887', 'burlywood'), ('#D2B48C', 'tan'), ('#FFDEAD', 'navajowhite'), ('#FFA500', 'orange'), ('#B8860B', 'darkgoldenrod'), ('#DAA520', 'goldenrod'), ('#FFD700', 'gold'), ('#F0E68C', 'khaki'), ('#BDB76B', 'darkkhaki'), ('#808000', 'olive'), ('#FFFF00', 'yellow'), ('#6B8E23', 'olivedrab'), ('#9ACD32', 'yellowgreen'), ('#556B2F', 'darkolivegreen'), ('#ADFF2F', 'greenyellow'), ('#7FFF00', 'chartreuse'), ('#7CFC00', 'lawngreen'), ('#98FB98', 'palegreen'), ('#90EE90', 'lightgreen'), ('#228B22', 'forestgreen'), ('#32CD32', 'limegreen'), ('#006400', 'darkgreen'), ('#008000', 'green'), ('#00FF00', 'lime'), ('#2E8B57', 'seagreen'), ('#3CB371', 'mediumseagreen'), ('#00FF7F', 'springgreen'), ('#00FA9A', 'mediumspringgreen'), ('#66CDAA', 'mediumaquamarine'), ('#7FFFD4', 'aquamarine'), ('#40E0D0', 'turquoise'), ('#20B2AA', 'lightseagreen'), ('#48D1CC', 'mediumturquoise'), ('#2F4F4F', 'darkslategray'), ('#2F4F4F', 'darkslategrey'), ('#008080', 'teal'), ('#008B8B', 'darkcyan'), ('#00FFFF', 'aqua'), ('#00FFFF', 'cyan'), ('#00CED1', 'darkturquoise'), ('#5F9EA0', 'cadetblue'), ('#00BFFF', 'deepskyblue'), ('#87CEEB', 'skyblue'), ('#87CEFA', 'lightskyblue'), ('#4682B4', 'steelblue'), ('#1E90FF', 'dodgerblue'), ('#6495ED', 'cornflowerblue'), ('#4169E1', 'royalblue'), ('#191970', 'midnightblue'), ('#000080', 'navy'), ('#00008B', 'darkblue'), ('#0000CD', 'mediumblue'), ('#0000FF', 'blue'), ('#6A5ACD', 'slateblue'), ('#483D8B', 'darkslateblue'), ('#7B68EE', 'mediumslateblue'), ('#9370DB', 'mediumpurple'), ('#663399', 'rebeccapurple'), ('#8A2BE2', 'blueviolet'), ('#4B0082', 'indigo'), ('#9932CC', 'darkorchid'), ('#9400D3', 'darkviolet'), ('#BA55D3', 'mediumorchid'), ('#EE82EE', 'violet'), ('#800080', 'purple'), ('#8B008B', 'darkmagenta'), ('#FF00FF', 'fuchsia'), ('#FF00FF', 'magenta'), ('#DA70D6', 'orchid'), ('#C71585', 'mediumvioletred'), ('#FF1493', 'deeppink'), ('#FF69B4', 'hotpink'), ('#DB7093', 'palevioletred'), ('#DC143C', 'crimson'), ('#6A3B71', 'CCPNpurple'), ('#2F705C', 'CCPNgreen'), ('#BD9D46', 'CCPNyellow'), ('#0C4F83', 'CCPNblue'), ]) # all colours defined in the matplotlib colourspace + new CCPN colours allColours = OrderedDict([('#000000', 'black'), ('#696969', 'dimgray'), ('#696969', 'dimgrey'), ('#808080', 'gray'), ('#808080', 'grey'), ('#A9A9A9', 'darkgray'), ('#A9A9A9', 'darkgrey'), ('#C0C0C0', 'silver'), ('#D3D3D3', 'lightgray'), ('#D3D3D3', 'lightgrey'), ('#DCDCDC', 'gainsboro'), ('#F5F5F5', 'whitesmoke'), ('#FFFFFF', 'white'), ('#FFFAFA', 'snow'), ('#BC8F8F', 'rosybrown'), ('#F08080', 'lightcoral'), ('#CD5C5C', 'indianred'), ('#A52A2A', 'brown'), ('#B22222', 'firebrick'), ('#800000', 'maroon'), ('#8B0000', 'darkred'), ('#FF0000', 'red'), ('#FFE4E1', 'mistyrose'), ('#FA8072', 'salmon'), ('#FF6347', 'tomato'), ('#E9967A', 'darksalmon'), ('#FF7F50', 'coral'), ('#FF4500', 'orangered'), ('#FFA07A', 'lightsalmon'), ('#A0522D', 'sienna'), ('#FFF5EE', 'seashell'), ('#D2691E', 'chocolate'), ('#8B4513', 'saddlebrown'), ('#F4A460', 'sandybrown'), ('#FFDAB9', 'peachpuff'), ('#CD853F', 'peru'), ('#FAF0E6', 'linen'), ('#FFE4C4', 'bisque'), ('#FF8C00', 'darkorange'), ('#DEB887', 'burlywood'), ('#FAEBD7', 'antiquewhite'), ('#D2B48C', 'tan'), ('#FFDEAD', 'navajowhite'), ('#FFEBCD', 'blanchedalmond'), ('#FFEFD5', 'papayawhip'), ('#FFE4B5', 'moccasin'), ('#FFA500', 'orange'), ('#F5DEB3', 'wheat'), ('#FDF5E6', 'oldlace'), ('#FFFAF0', 'floralwhite'), ('#B8860B', 'darkgoldenrod'), ('#DAA520', 'goldenrod'), ('#FFF8DC', 'cornsilk'), ('#FFD700', 'gold'), ('#FFFACD', 'lemonchiffon'), ('#F0E68C', 'khaki'), ('#EEE8AA', 'palegoldenrod'), ('#BDB76B', 'darkkhaki'), ('#FFFFF0', 'ivory'), ('#F5F5DC', 'beige'), ('#FFFFE0', 'lightyellow'), ('#FAFAD2', 'lightgoldenrodyellow'), ('#808000', 'olive'), ('#FFFF00', 'yellow'), ('#6B8E23', 'olivedrab'), ('#9ACD32', 'yellowgreen'), ('#556B2F', 'darkolivegreen'), ('#ADFF2F', 'greenyellow'), ('#7FFF00', 'chartreuse'), ('#7CFC00', 'lawngreen'), ('#F0FFF0', 'honeydew'), ('#8FBC8F', 'darkseagreen'), ('#98FB98', 'palegreen'), ('#90EE90', 'lightgreen'), ('#228B22', 'forestgreen'), ('#32CD32', 'limegreen'), ('#006400', 'darkgreen'), ('#008000', 'green'), ('#00FF00', 'lime'), ('#2E8B57', 'seagreen'), ('#3CB371', 'mediumseagreen'), ('#00FF7F', 'springgreen'), ('#F5FFFA', 'mintcream'), ('#00FA9A', 'mediumspringgreen'), ('#66CDAA', 'mediumaquamarine'), ('#7FFFD4', 'aquamarine'), ('#40E0D0', 'turquoise'), ('#20B2AA', 'lightseagreen'), ('#48D1CC', 'mediumturquoise'), ('#F0FFFF', 'azure'), ('#E0FFFF', 'lightcyan'), ('#AFEEEE', 'paleturquoise'), ('#2F4F4F', 'darkslategray'), ('#2F4F4F', 'darkslategrey'), ('#008080', 'teal'), ('#008B8B', 'darkcyan'), ('#00FFFF', 'aqua'), ('#00FFFF', 'cyan'), ('#00CED1', 'darkturquoise'), ('#5F9EA0', 'cadetblue'), ('#B0E0E6', 'powderblue'), ('#ADD8E6', 'lightblue'), ('#00BFFF', 'deepskyblue'), ('#87CEEB', 'skyblue'), ('#87CEFA', 'lightskyblue'), ('#4682B4', 'steelblue'), ('#F0F8FF', 'aliceblue'), ('#1E90FF', 'dodgerblue'), ('#778899', 'lightslategray'), ('#778899', 'lightslategrey'), ('#708090', 'slategray'), ('#708090', 'slategrey'), ('#B0C4DE', 'lightsteelblue'), ('#6495ED', 'cornflowerblue'), ('#4169E1', 'royalblue'), ('#F8F8FF', 'ghostwhite'), ('#E6E6FA', 'lavender'), ('#191970', 'midnightblue'), ('#000080', 'navy'), ('#00008B', 'darkblue'), ('#0000CD', 'mediumblue'), ('#0000FF', 'blue'), ('#6A5ACD', 'slateblue'), ('#483D8B', 'darkslateblue'), ('#7B68EE', 'mediumslateblue'), ('#9370DB', 'mediumpurple'), ('#663399', 'rebeccapurple'), ('#8A2BE2', 'blueviolet'), ('#4B0082', 'indigo'), ('#9932CC', 'darkorchid'), ('#9400D3', 'darkviolet'), ('#BA55D3', 'mediumorchid'), ('#D8BFD8', 'thistle'), ('#DDA0DD', 'plum'), ('#EE82EE', 'violet'), ('#800080', 'purple'), ('#8B008B', 'darkmagenta'), ('#FF00FF', 'fuchsia'), ('#FF00FF', 'magenta'), ('#DA70D6', 'orchid'), ('#C71585', 'mediumvioletred'), ('#FF1493', 'deeppink'), ('#FF69B4', 'hotpink'), ('#FFF0F5', 'lavenderblush'), ('#DB7093', 'palevioletred'), ('#DC143C', 'crimson'), ('#FFC0CB', 'pink'), ('#FFB6C1', 'lightpink'), ('#6A3B71', 'CCPNpurple'), ('#2F705C', 'CCPNgreen'), ('#BD9D46', 'CCPNyellow'), ('#0C4F83', 'CCPNblue'), ]) # default color schemes colorSchemeTable = OrderedDict([('redshade', ('#FFC0C0', '#FF9A9A', '#FF7373', '#FF4D4D', '#FF2626', '#FF0000', '#D90000', '#B30000', '#8C0000', '#660000')), ('orangeshade', ('#FFE0C0', '#FFC890', '#FFB060', '#FF9830', '#FF8000', '#E17100', '#C26100', '#A35200', '#854200', '#663300')), ('yellowshade', ('#FFFF99', '#FFFF4C', '#FFFF00', '#E7E700', '#CFCF00', '#B6B600', '#9E9E00', '#868600', '#6D6D00', '#555500')), ('greenshade', ('#99FF99', '#73F073', '#4CE04C', '#26D026', '#00C000', '#00AE00', '#009C00', '#008A00', '#007800', '#006600')), ('blueshade', ('#C0C0FF', '#9A9AFF', '#7373FF', '#4D4DFF', '#2626FF', '#0000FF', '#0000D9', '#0000B3', '#00008C', '#000066')), ('cyanshade', ('#00FFFF', '#00ECEC', '#00D8D8', '#00C4C4', '#00B0B0', '#009C9C', '#008888', '#007474', '#006060', '#004C4C')), ('purpleshade', ('#E6CCFF', '#D399F0', '#C066E0', '#AC33D0', '#9900C0', '#8500AC', '#700097', '#5C0082', '#47006E', '#330059')), ('greyshade', ('#CCCCCC', '#BBBBBB', '#AAAAAA', '#999999', '#888888', '#777777', '#666666', '#555555', '#444444', '#333333')), ('redshade2', ('#660000', '#8C0000', '#B30000', '#D90000', '#FF0000', '#FF2626', '#FF4D4D', '#FF7373', '#FF9A9A', '#FFC0C0')), ('orangeshade2', ('#663300', '#854200', '#A35200', '#C26100', '#E17100', '#FF8000', '#FF9830', '#FFB060', '#FFC890', '#FFE0C0')), ('yellowshade2', ('#555500', '#6D6D00', '#868600', '#9E9E00', '#B6B600', '#CFCF00', '#E7E700', '#FFFF00', '#FFFF4C', '#FFFF99')), ('greenshade2', ('#006600', '#007800', '#008A00', '#009C00', '#00AE00', '#00C000', '#26D026', '#4CE04C', '#73F073', '#99FF99')), ('blueshade2', ('#000066', '#00008C', '#0000B3', '#0000D9', '#0000FF', '#2626FF', '#4D4DFF', '#7373FF', '#9A9AFF', '#C0C0FF')), ('cyanshade2', ('#004C4C', '#006060', '#007474', '#008888', '#009C9C', '#00B0B0', '#00C4C4', '#00D8D8', '#00ECEC', '#00FFFF')), ('purpleshade2', ('#330059', '#47006E', '#5C0082', '#700097', '#8500AC', '#9900C0', '#AC33D0', '#C066E0', '#D399F0', '#E6CCFF')), ('greyshade2', ('#333333', '#444444', '#555555', '#666666', '#777777', '#888888', '#999999', '#AAAAAA', '#BBBBBB', '#CCCCCC')), ('rainbow', ( '#FF00FF', '#FF0080', '#FF0000', '#FF8000', '#FFFF00', '#80FF00', '#00FF00', '#00FF80', '#00FFFF', '#0080FF', '#0000FF', '#8000FF')), ('rainbow2', ('#8000FF', '#0000FF', '#0080FF', '#00FFFF', '#00FF80', '#00FF00', '#80FF00', '#FFFF00', '#FF8000', '#FF0000', '#FF0080', '#FF00FF')), ('wimbledon', ('#008000', '#1C8E00', '#389C00', '#55AB00', '#71B900', '#8EC700', '#AAD500', '#C7E300', '#E3F100', '#FFFF00')), ('wimbledon2', ('#FFFF00', '#E3F100', '#C7E300', '#AAD500', '#8EC700', '#71B900', '#55AB00', '#389C00', '#1C8E00', '#008000')), ('toothpaste', ('#C0C0FF', '#9A9AFF', '#7373FF', '#4D4DFF', '#2626FF', '#0000FF', '#0040FF', '#0080FF', '#00C0FF', '#00FFFF')), ('toothpaste2', ('#00FFFF', '#00C0FF', '#0080FF', '#0040FF', '#0000FF', '#2626FF', '#4D4DFF', '#7373FF', '#9A9AFF', '#C0C0FF')), ('cmy', ('#00FFFF', '#33CCFF', '#6699FF', '#9966FF', '#CC33FF', '#FF00FF', '#FF33CC', '#FF6699', '#FF9966', '#FFCC33', '#FFFF00')), ('cmy2', ('#FFFF00', '#FFCC33', '#FF9966', '#FF6699', '#FF33CC', '#FF00FF', '#CC33FF', '#9966FF', '#6699FF', '#33CCFF', '#00FFFF')), ('steel', ('#C0C0C0', '#ABABB9', '#9595B2', '#8080AB', '#6B6BA4', '#55559D', '#404095', '#2A2A8E', '#151587', '#000080')), ('steel2', ('#000080', '#151587', '#2A2A8E', '#404095', '#55559D', '#6B6BA4', '#8080AB', '#9595B2', '#ABABB9', '#C0C0C0')), ('rgb', ('#FF0000', '#CC1900', '#993300', '#664D00', '#336600', '#008000', '#006633', '#004D66', '#003399', '#0019CC', '#0000FF')), ('rgb2', ('#0000FF', '#0019CC', '#003399', '#004D66', '#006633', '#008000', '#336600', '#664D00', '#993300', '#CC1900', '#FF0000')), ('tropicana', ('#FFFF00', '#FFE30E', '#FFC71C', '#FFAA2A', '#FF8E39', '#FF7147', '#FF5555', '#FF3863', '#FF1C72', '#FF0080')), ('tropicana2', ('#FF0080', '#FF1C72', '#FF3863', '#FF5555', '#FF7147', '#FF8E39', '#FFAA2A', '#FFC71C', '#FFE30E', '#FFFF00')), ('sunset', ('#FFC0C0', '#FF9A9A', '#FF7373', '#FF4D4D', '#FF2626', '#FF0000', '#FF4000', '#FF8000', '#FFC000', '#FFFF00')), ('sunset2', ('#FFFF00', '#FFC000', '#FF8000', '#FF4000', '#FF0000', '#FF2626', '#FF4D4D', '#FF7373', '#FF9A9A', '#FFC0C0')), ('magma', ('#000000', '#400000', '#800000', '#C00000', '#FF0000', '#FF3300', '#FF6600', '#FF9900', '#FFCC00', '#FFFF00')), ('magma2', ('#FFFF00', '#FFCC00', '#FF9900', '#FF6600', '#FF3300', '#FF0000', '#C00000', '#800000', '#400000', '#000000')), ('holly', ('#80FF80', '#66E666', '#4DCD4D', '#33B333', '#199A19', '#008000', '#FF0000', '#D50000', '#AB0000', '#800000')), ('holly2', ('#800000', '#AB0000', '#D50000', '#FF0000', '#008000', '#199A19', '#33B333', '#4DCD4D', '#66E666', '#80FF80')), ('glacier', ('#000000', '#000040', '#000080', '#0000C0', '#0000FF', '#2626FF', '#4D4DFF', '#7373FF', '#9A9AFF', '#C0C0FF')), ('glacier2', ('#C0C0FF', '#9A9AFF', '#7373FF', '#4D4DFF', '#2626FF', '#0000FF', '#0000C0', '#000080', '#000040', '#000000')), ('monarchy', ('#C0C0FF', '#6060FF', '#0000FF', '#3300CC', '#660099', '#990066', '#CC0033', '#FF0000', '#C00000', '#800000')), ('monarchy2', ('#800000', '#C00000', '#FF0000', '#CC0033', '#990066', '#660099', '#3300CC', '#0000FF', '#6060FF', '#C0C0FF')), ('contrast', ('#FF0000', '#008000', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF')), ('contrast2', ('#00FFFF', '#FF00FF', '#FFFF00', '#0000FF', '#008000', '#FF0000')), ('lightspectrum', ( '#6B8E23', '#DA70D6', '#8A2BE2', '#808000', '#1E90FF', '#FFA500', '#FF0000', '#4682B4', '#7FFF00', '#9932CC', '#A0522D', '#00CED1', '#00FFFF', '#FFFF00', '#FF1493', '#32CD32')), ('lightspectrum2', ( '#32CD32', '#FF1493', '#FFFF00', '#00FFFF', '#00CED1', '#A0522D', '#9932CC', '#7FFF00', '#4682B4', '#FF0000', '#FFA500', '#1E90FF', '#808000', '#8A2BE2', '#DA70D6', '#6B8E23')), ('red-orange', ('#ff2010', '#ff3414', '#ff4818', '#ff5c1c', '#ff7020', '#ff8424', '#ff9828', '#ffac2c', '#ffc030')), ('orange-yellow', ('#ffc030', '#fcc72c', '#facf28', '#f8d724', '#f6df20', '#f4e71c', '#f2ef18', '#f0f714', '#eeff10')), ('yellow-green', ('#eeff10', '#d2f812', '#b6f214', '#9aeb16', '#7fe518', '#63df1a', '#47d81c', '#2bd21e', '#10cc20')), ('green-blue', ('#10cc20', '#12b43b', '#149d57', '#168573', '#186e8f', '#1a56ab', '#1c3fc7', '#1e27e3', '#2010ff')), ('blue-cyan', ('#2010ff', '#202bff', '#2047ff', '#2063ff', '#207fff', '#209aff', '#20b6ff', '#20d2ff', '#20eeff')), ('blue-purple', ('#2010ff', '#3912ff', '#5314ff', '#6d16ff', '#8718ff', '#a01aff', '#ba1cff', '#d41eff', '#ee20ff')), ('orange-red', ('#ffc030', '#ffac2c', '#ff9828', '#ff8424', '#ff7020', '#ff5c1c', '#ff4818', '#ff3414', '#ff2010')), ('yellow-orange', ('#eeff10', '#f0f714', '#f2ef18', '#f4e71c', '#f6df20', '#f8d724', '#facf28', '#fcc72c', '#ffc030')), ('green-yellow', ('#10cc20', '#2bd21e', '#47d81c', '#63df1a', '#7fe518', '#9aeb16', '#b6f214', '#d2f812', '#eeff10')), ('blue-green', ('#2010ff', '#1e27e3', '#1c3fc7', '#1a56ab', '#186e8f', '#168573', '#149d57', '#12b43b', '#10cc20')), ('cyan-blue', ('#20eeff', '#20d2ff', '#20b6ff', '#209aff', '#207fff', '#2063ff', '#2047ff', '#202bff', '#2010ff')), ('purple-blue', ('#ee20ff', '#d41eff', '#ba1cff', '#a01aff', '#8718ff', '#6d16ff', '#5314ff', '#3912ff', '#2010ff')), ('black-white', ('#000000', '#1f1f1f', '#3f3f3f', '#5f5f5f', '#7f7f7f', '#9f9f9f', '#bfbfbf', '#dfdfdf', '#ffffff')), ('white-black', ('#ffffff', '#dfdfdf', '#bfbfbf', '#9f9f9f', '#7f7f7f', '#5f5f5f', '#3f3f3f', '#1f1f1f', '#000000')), ('black-gray', ('#000000', '#0f0f0f', '#1f1f1f', '#2f2f2f', '#3f3f3f', '#4f4f4f', '#5f5f5f', '#6f6f6f', '#7f7f7f')), ('gray-black', ('#7f7f7f', '#6f6f6f', '#5f5f5f', '#4f4f4f', '#3f3f3f', '#2f2f2f', '#1f1f1f', '#0f0f0f', '#000000')), ]) allColoursWithSpaces = OrderedDict([(k, colourNameWithSpace(v)) for k, v in allColours.items()]) # set the spectrum colours to all, override minimum set above spectrumColours = brightColours # split the colour palettes into light and dark for different colour schemes spectrumDarkColours = OrderedDict() spectrumLightColours = OrderedDict() spectrumMediumColours = OrderedDict() for k, v in spectrumColours.items(): h = hexToRgb(k) # colour can belong to both sets if gray(*h) > COLOUR_LIGHT_THRESHOLD: spectrumLightColours[k] = v if gray(*h) < COLOUR_DARK_THRESHOLD: spectrumDarkColours[k] = v if gray(*h) > COLOUR_LIGHT_THRESHOLD and gray(*h) < COLOUR_DARK_THRESHOLD: spectrumMediumColours[k] = v allDarkColours = OrderedDict() allLightColours = OrderedDict() allMediumColours = OrderedDict() for k, v in allColours.items(): h = hexToRgb(k) # colour can belong to both sets if gray(*h) > COLOUR_LIGHT_THRESHOLD: allLightColours[k] = v if gray(*h) < COLOUR_DARK_THRESHOLD: allDarkColours[k] = v if gray(*h) > COLOUR_LIGHT_THRESHOLD and gray(*h) < COLOUR_DARK_THRESHOLD: allMediumColours[k] = v spectrumHexLightColours = tuple(ky for ky in spectrumLightColours.keys() if ky != '#') spectrumHexDarkColours = tuple(ky for ky in spectrumDarkColours.keys() if ky != '#') spectrumHexMediumColours = tuple(ky for ky in spectrumMediumColours.keys() if ky != '#') spectrumHexDefaultLightColours = tuple(ky for ky in lightDefaultSpectrumColours.keys() if ky != '#') spectrumHexDefaultDarkColours = tuple(ky for ky in darkDefaultSpectrumColours.keys() if ky != '#') # override this with spectrumLight/DarkColours when colourScheme is changed spectrumHexColours = tuple(ky for ky in spectrumColours.keys() if ky != '#') # Note that Colour strings are not re-used
[docs]class Colour(str): """ A class to make colour manipulation easier and more transparent. Assumes that r, g, b values are 8-bit so between 0 and 255 and have optional a. >>> c = Colour('magenta') >>> c = Colour('#FF00FF') >>> c = Colour((255, 0, 255)) """ def __init__(self, value): """ value can be name or #rrggbb or #rrggbbaa or (r, g, b) or (r, g, b, a) tuple/list """ # print(value, 'color init') if not value: raise Exception('not allowed blank colour') if isinstance(value, str): value = value.lower() name = value if value[0] != '#': value = colourNameToHexDict[name] assert len(value) in (7, 9), 'len(value) = %d, should be 7 or 9' % len(value) r = int(value[1:3], 16) g = int(value[3:5], 16) b = int(value[5:7], 16) a = int(value[7:9], 16) if len(value) == 9 else 255 else: assert isinstance(value, list) or isinstance(value, tuple), 'value must be list or tuple if it is not a string, was %s' % ( value,) assert len(value) in (3, 4), 'value=%s, len(value) = %d, should be 3 or 4' % (value, len(value)) r, g, b = value[:3] if len(value) == 4: a = value[3] name = rgbaToHex(r, g, b, a) else: a = 255 name = rgbToHex(r, g, b) ###str.__init__(self) self.r = r self.g = g self.b = b self.a = a self.name = name
[docs] def rgba(self): """Returns 4-tuple of (r, g, b, a) where each one is in range 0 to 255""" return (self.r, self.g, self.b, self.a)
[docs] def scaledRgba(self): """Returns 4-tuple of (r, g, b, a) where each one is in range 0.0 to 1.0""" return (self.r / 255.0, self.g / 255.0, self.b / 255.0, self.a / 255.0)
[docs] def hex(self): return '#' + ''.join([_ccpnHex(x)[2:] for x in (self.r, self.g, self.b)])
def __repr__(self): return self.name def __str__(self): return self.__repr__()
[docs]def rgba(value): return Colour(value).rgba()
[docs]def scaledRgba(value): # print(value, 'scaledRgba') return Colour(value).scaledRgba()
[docs]def addNewColour(newColour): newIndex = str(len(spectrumColours.items()) + 1) spectrumColours[newColour.name()] = 'Colour %s' % newIndex
[docs]def isSpectrumColour(colourString): """Return true if the colourString is in the list """ return colourString in list(spectrumColours.keys())
[docs]def addNewColourString(colourString): """Add a new Hex colour to the colourlist New colour has the name 'Colour <n>' where n is the next free number """ # '#' is reserved for auto colour so shouldn't ever be added if colourString != '#' and colourString not in spectrumColours: newIndex = str(len(spectrumColours.items()) + 1) spectrumColours[colourString] = 'Colour %s' % newIndex
[docs]def autoCorrectHexColour(colour, referenceHexColour='#ffffff', addNewColour=True): """Autocorrect colours if too close to the reference value """ if colour == '#': return colour g = gray(*hexToRgb(colour)) rgb = hexToRgb(referenceHexColour) gRef = gray(*rgb) if abs(g - gRef) < COLOUR_THRESHOLD: newCol = invertRGBLuma(*hexToRgb(colour)) hx = rgbToHex(*newCol) if addNewColour: addNewColourString(hx) return hx return colour
# def _setNewColour(colList, newCol:str): # # # check if the colour is in the spectrumColours list # # # check if colour is in you colList # # # pix = QtGui.QPixmap(QtCore.QSize(20, 20)) # pix.fill(QtGui.QColor(newCol)) # # # add the new colour to the spectrumColours dict # newIndex = str(len(spectrumColours.items()) + 1) # # spectrumColours[newColour.name()] = 'Colour %s' % newIndex # addNewColourString(newCol) # if newCol not in colList.texts: # colList.addItem(icon=QtGui.QIcon(pix), text='Colour %s' % newIndex) # colList.setCurrentIndex(int(newIndex) - 1)
[docs]def selectPullDownColour(pulldown, colourString, allowAuto=False): # try: # pulldown.setCurrentText(spectrumColours[colourString]) # except: # if allowAuto and '#' in pulldown.texts: # pulldown.setCurrentText('#') if colourString in spectrumColours: pulldown.setCurrentText(spectrumColours[colourString]) elif colourString in colorSchemeTable: pulldown.setCurrentText(colourString) elif allowAuto and '<auto>' in pulldown.texts: pulldown.setCurrentText('<auto>')
# ICON_SIZE = 20
[docs]def fillColourPulldown(pulldown, allowAuto=False, allowNone=False, includeGradients=True): # fill the pulldown with the list of colours # this has no signals blocked otherwise it doesn't paint, and should be signalBlocked elsewhere currText = pulldown.currentText() ICON_SIZE = max(getFontHeight(size='MEDIUM') or 16, 16) pulldown.clear() if allowAuto: pulldown.addItem(text='<auto>') if allowNone: pulldown.addItem(text='') for item in spectrumColours.items(): # if item[1] not in pulldown.texts: colName = item[1] # colourNameWithSpace(item[1]) if item[0] != '#': pix = QtGui.QPixmap(QtCore.QSize(ICON_SIZE, ICON_SIZE)) pix.fill(QtGui.QColor(item[0])) pulldown.addItem(icon=QtGui.QIcon(pix), text=colName) elif allowAuto: pulldown.addItem(text=colName) if includeGradients: for colName, colourList in colorSchemeTable.items(): pix = QtGui.QPixmap(QtCore.QSize(ICON_SIZE, ICON_SIZE)) step = ICON_SIZE stepX = ICON_SIZE stepY = len(colourList) - 1 jj = 0 painter = QtGui.QPainter(pix) for ii in range(ICON_SIZE): _interp = (stepX - step) / stepX _intCol = interpolateColourHex(colourList[min(jj, stepY)], colourList[min(jj + 1, stepY)], _interp) painter.setPen(QtGui.QColor(_intCol)) painter.drawLine(ii, 0, ii, ICON_SIZE) step -= stepY while step < 0: step += stepX jj += 1 painter.end() pulldown.addItem(icon=QtGui.QIcon(pix), text=colName) pulldown.setCurrentText(currText)
def _setColourPulldown(pulldown, attrib, allowAuto=False, includeGradients=True, allowNone=False): """Populate colour pulldown and set to the current colour """ spectrumColourKeys = list(spectrumColours.keys()) fillColourPulldown(pulldown, allowAuto=allowAuto, includeGradients=includeGradients, allowNone=allowNone) c = attrib.upper() if attrib and attrib.startswith('#') else attrib if c in spectrumColourKeys: col = spectrumColours[c] pulldown.setCurrentText(col) elif attrib in colorSchemeTable: pulldown.setCurrentText(attrib) elif c is None: if allowNone: pulldown.setCurrentText('') else: addNewColourString(c) fillColourPulldown(pulldown, allowAuto=allowAuto, includeGradients=includeGradients, allowNone=allowNone) if c != '#' or allowAuto is True: col = spectrumColours[c] pulldown.setCurrentText(col)
[docs]def getSpectrumColour(colourName, defaultReturn=None): """ return the hex colour of the named colour """ try: colName = colourName # colourNameNoSpace(colourName) if colName in spectrumColours.values(): col = list(spectrumColours.keys())[list(spectrumColours.values()).index(colName)] return col.upper() if col.startswith('#') else col elif colName in colorSchemeTable: return colName else: return defaultReturn except: # colour not found in the list return defaultReturn
[docs]def getAutoColourRgbRatio(inColour=None, sourceObject=None, colourAttribute=None, defaultColour=None): listColour = inColour if listColour == '#': listColour = getattr(sourceObject, colourAttribute, defaultColour) if listColour in colorSchemeTable: # get the first item from the colour gradient listColour = colorSchemeTable[listColour][0] return hexToRgbRatio(listColour) or defaultColour
[docs]def findNearestHex(hexCol, colourHexList): weights = (0.3, 0.59, 0.11) # assuming rgb rgbIn = hexToRgb(hexCol) lastCol = None for col in colourHexList: rgbTest = hexToRgb(col) # use euclidean to find closest colour num = 0.0 for a, b, w in zip(rgbIn, rgbTest, weights): num += pow((a - b) * w, 4) if lastCol is None or num < lastDiff: lastDiff = num lastCol = (col, num) return lastCol[0]
if __name__ == '__main__': """Simple routine to plot all the named colors in the matplotlib colorspace """ import matplotlib.pyplot as plt from matplotlib import colors as mcolors colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS) def colourPlot(names, title='ColourPlot'): """make a colour plot of the names """ n = len(names) ncols = 4 nrows = n // ncols + 1 fig, ax = plt.subplots(figsize=(16, 9)) # Get height and width X, Y = fig.get_dpi() * fig.get_size_inches() Y0 = Y - fig.get_dpi() * 1.0 # remove an inch from the size h = Y0 // max((nrows + 1), 15) w = X // ncols for i, name in enumerate(names): row = i % nrows col = i // nrows y = Y0 - (row * h) - h xi_line = w * (col + 0.05) xf_line = w * (col + 0.25) xi_text = w * (col + 0.3) ax.text(xi_text, y, name, fontsize=(h * 0.5), horizontalalignment='left', verticalalignment='center') if name in colors: ax.hlines(y + h * 0.1, xi_line, xf_line, color=colors[name] if name in colors else name, linewidth=(h * 0.6)) ax.set_xlim(0, X) ax.set_ylim(0, Y) ax.set_axis_off() ax.text(fig.get_dpi() * 0.25, Y - fig.get_dpi() * 0.5, title, fontsize=fig.get_dpi() * 0.25, horizontalalignment='left', verticalalignment='center') fig.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0) plt.show() # Sort colors by hue, saturation, value and name. by_hsv = sorted((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name) for name, color in colors.items()) sorted_names = [name for hsv, name in by_hsv if (hsv[0] == 0.0 and hsv[1] == 0.0) or hsv[1] > 0.3] # print the colors to generate full colorList for col in sorted_names: if isinstance(colors[col], str): # col = colourNameWithSpace(col) print('(' + repr(colors[col]) + ', ' + repr(col) + '),') colourPlot(spectrumDarkColours.values(), title='Dark Spectrum Colours') colourPlot(spectrumMediumColours.values(), title='Medium Spectrum Colours') colourPlot(spectrumLightColours.values(), title='Light Spectrum Colours') thisPalette = spectrumLightColours colourPlot(thisPalette.values(), title='Light Default Spectrum Colours') opposites = [] for col in thisPalette.keys(): rgbIn = hexToRgb(col) negRGB = invertRGBHue(*rgbIn) oppCol = rgbToHex(*negRGB) oppCol = findNearestHex(oppCol, thisPalette.keys()) opposites.append(thisPalette[oppCol]) colourPlot(opposites, title='Light Inverted Colours') thisPalette = spectrumDarkColours colourPlot(thisPalette.values(), title='Dark Default Spectrum Colours') opposites = [] for col in thisPalette.keys(): rgbIn = hexToRgb(col) negRGB = invertRGBHue(*rgbIn) oppCol = rgbToHex(*negRGB) oppCol = findNearestHex(oppCol, thisPalette.keys()) opposites.append(thisPalette[oppCol]) colourPlot(opposites, title='Dark Inverted Colours')
[docs]def interpolateColourRgba(colour1, colour2, value, alpha=1.0): result = [(col1 + (col2 - col1) * value) for col1, col2 in zip(colour1, colour2)] while len(result) < 4: result.append(alpha) return tuple(result[:4])
[docs]def interpolateColourHex(hexColor1, hexColor2, value, alpha=1.0): if hexColor1 is None or hexColor2 is None: return None value = np.clip(value, 0.0, 1.0) r1 = int('0x' + hexColor1[1:3], 16) g1 = int('0x' + hexColor1[3:5], 16) b1 = int('0x' + hexColor1[5:7], 16) r2 = int('0x' + hexColor2[1:3], 16) g2 = int('0x' + hexColor2[3:5], 16) b2 = int('0x' + hexColor2[5:7], 16) colour1 = (r1, g1, b1) colour2 = (r2, g2, b2) result = [(col1 + (col2 - col1) * value) for col1, col2 in zip(colour1, colour2)] return '#%02x%02x%02x' % (int(result[0]), int(result[1]), int(result[2]))
# ('darkredshade', ('#7f6060', '#7f4d4d', '#7f3939', '#7f2626', '#7f1313', '#7f0000', '#6c0000', '#590000', '#460000', '#330000')), # ('darkorangeshade', ('#7f7060', '#7f6448', '#7f5830', '#7f4c18', '#7f4000', '#703800', '#613000', '#512900', '#422100', '#331900')), # ('darkyellowshade', ('#7f7f4c', '#7f7f26', '#7f7f00', '#737300', '#676700', '#5b5b00', '#4f4f00', '#434300', '#363600', '#2a2a00')), # ('darkgreenshade', ('#4c7f4c', '#397839', '#267026', '#136813', '#006000', '#005700', '#004e00', '#004500', '#003c00', '#003300')), # ('darkblueshade', ('#60607f', '#4d4d7f', '#39397f', '#26267f', '#13137f', '#00007f', '#00006c', '#000059', '#000046', '#000033')), # ('darkcyanshade', ('#007f7f', '#007676', '#006c6c', '#006262', '#005858', '#004e4e', '#004444', '#003a3a', '#003030', '#002626')), # ('darkpurpleshade', ('#73667f', '#694c78', '#603370', '#561968', '#4c0060', '#420056', '#38004b', '#2e0041', '#230037', '#19002c')), # ('darkgreyshade', ('#666666', '#5d5d5d', '#555555', '#4c4c4c', '#444444', '#3b3b3b', '#333333', '#2a2a2a', '#222222', '#191919')), # ('darkredshade2', ('#330000', '#460000', '#590000', '#6c0000', '#7f0000', '#7f1313', '#7f2626', '#7f3939', '#7f4d4d', '#7f6060')), # ('darkorangeshade2', ('#331900', '#422100', '#512900', '#613000', '#703800', '#7f4000', '#7f4c18', '#7f5830', '#7f6448', '#7f7060')), # ('darkyellowshade2', ('#2a2a00', '#363600', '#434300', '#4f4f00', '#5b5b00', '#676700', '#737300', '#7f7f00', '#7f7f26', '#7f7f4c')), # ('darkgreenshade2', ('#003300', '#003c00', '#004500', '#004e00', '#005700', '#006000', '#136813', '#267026', '#397839', '#4c7f4c')), # ('darkblueshade2', ('#000033', '#000046', '#000059', '#00006c', '#00007f', '#13137f', '#26267f', '#39397f', '#4d4d7f', '#60607f')), # ('darkcyanshade2', ('#002626', '#003030', '#003a3a', '#004444', '#004e4e', '#005858', '#006262', '#006c6c', '#007676', '#007f7f')), # ('darkpurpleshade2', ('#19002c', '#230037', '#2e0041', '#38004b', '#420056', '#4c0060', '#561968', '#603370', '#694c78', '#73667f')), # ('darkgreyshade2', ('#191919', '#222222', '#2a2a2a', '#333333', '#3b3b3b', '#444444', '#4c4c4c', '#555555', '#5d5d5d', '#666666')), # # ('darkrainbow', # ('#7f007f', '#7f0040', '#7f0000', '#7f4000', '#7f7f00', '#407f00', '#007f00', '#007f40', '#007f7f', '#00407f', '#00007f', '#40007f')), # ('darkrainbow2', # ('#40007f', '#00007f', '#00407f', '#007f7f', '#007f40', '#007f00', '#407f00', '#7f7f00', '#7f4000', '#7f0000', '#7f0040', '#7f007f')), # ('darkwimbledon', ('#004000', '#0e4700', '#1c4e00', '#2a5500', '#385c00', '#476300', '#556a00', '#637100', '#717800', '#7f7f00')), # ('darkwimbledon2', ('#7f7f00', '#717800', '#637100', '#556a00', '#476300', '#385c00', '#2a5500', '#1c4e00', '#0e4700', '#004000')), # ('darktoothpaste', ('#60607f', '#4d4d7f', '#39397f', '#26267f', '#13137f', '#00007f', '#00207f', '#00407f', '#00607f', '#007f7f')), # ('darktoothpaste2', ('#007f7f', '#00607f', '#00407f', '#00207f', '#00007f', '#13137f', '#26267f', '#39397f', '#4d4d7f', '#60607f')), # ('darkcmy', ('#007f7f', '#19667f', '#334c7f', '#4c337f', '#66197f', '#7f007f', '#7f1966', '#7f334c', '#7f4c33', '#7f6619', '#7f7f00')), # ('darkcmy2', ('#7f7f00', '#7f6619', '#7f4c33', '#7f334c', '#7f1966', '#7f007f', '#66197f', '#4c337f', '#334c7f', '#19667f', '#007f7f')), # ('darksteel', ('#606060', '#55555c', '#4a4a59', '#404055', '#353552', '#2a2a4e', '#20204a', '#151547', '#0a0a43', '#000040')), # ('darksteel2', ('#000040', '#0a0a43', '#151547', '#20204a', '#2a2a4e', '#353552', '#404055', '#4a4a59', '#55555c', '#606060')), # ('darkrgb', ('#7f0000', '#660c00', '#4c1900', '#332600', '#193300', '#004000', '#003319', '#002633', '#00194c', '#000c66', '#00007f')), # ('darkrgb2', ('#00007f', '#000c66', '#00194c', '#002633', '#003319', '#004000', '#193300', '#332600', '#4c1900', '#660c00', '#7f0000')), # ('darktropicana', ('#7f7f00', '#7f7107', '#7f630e', '#7f5515', '#7f471c', '#7f3823', '#7f2a2a', '#7f1c31', '#7f0e39', '#7f0040')), # ('darktropicana2', ('#7f0040', '#7f0e39', '#7f1c31', '#7f2a2a', '#7f3823', '#7f471c', '#7f5515', '#7f630e', '#7f7107', '#7f7f00')), # ('darksunset', ('#7f6060', '#7f4d4d', '#7f3939', '#7f2626', '#7f1313', '#7f0000', '#7f2000', '#7f4000', '#7f6000', '#7f7f00')), # ('darksunset2', ('#7f7f00', '#7f6000', '#7f4000', '#7f2000', '#7f0000', '#7f1313', '#7f2626', '#7f3939', '#7f4d4d', '#7f6060')), # ('darkmagma', ('#000000', '#200000', '#400000', '#600000', '#7f0000', '#7f1900', '#7f3300', '#7f4c00', '#7f6600', '#7f7f00')), # ('darkmagma2', ('#7f7f00', '#7f6600', '#7f4c00', '#7f3300', '#7f1900', '#7f0000', '#600000', '#400000', '#200000', '#000000')), # ('darkholly', ('#407f40', '#337333', '#266626', '#195919', '#0c4d0c', '#004000', '#7f0000', '#6a0000', '#550000', '#400000')), # ('darkholly2', ('#400000', '#550000', '#6a0000', '#7f0000', '#004000', '#0c4d0c', '#195919', '#266626', '#337333', '#407f40')), # ('darkglacier', ('#000000', '#000020', '#000040', '#000060', '#00007f', '#13137f', '#26267f', '#39397f', '#4d4d7f', '#60607f')), # ('darkglacier2', ('#60607f', '#4d4d7f', '#39397f', '#26267f', '#13137f', '#00007f', '#000060', '#000040', '#000020', '#000000')), # ('darkmonarchy', ('#60607f', '#30307f', '#00007f', '#190066', '#33004c', '#4c0033', '#660019', '#7f0000', '#600000', '#400000')), # ('darkmonarchy2', ('#400000', '#600000', '#7f0000', '#660019', '#4c0033', '#33004c', '#190066', '#00007f', '#30307f', '#60607f')), # ('darkcontrast', ('#7f0000', '#004000', '#00007f', '#7f7f00', '#7f007f', '#007f7f')), # ('darkcontrast2', ('#007f7f', '#7f007f', '#7f7f00', '#00007f', '#004000', '#7f0000')), # ('darkspectrum', ( # '#004040', '#6d386b', '#400040', '#404000', '#0f487f', '#7f5200', '#7f0000', '#23415a', '#004000', '#451571', '#400000', '#006768', '#000040', # '#7f2200', '#7f0a49', '#196619')), # ('darkspectrum2', ( # '#196619', '#7f0a49', '#7f2200', '#000040', '#006768', '#400000', '#451571', '#004000', '#23415a', '#7f0000', '#7f5200', '#0f487f', '#404000', # '#400040', '#6d386b', '#004040')), # ('darkred-orange', ('#7f1008', '#7f1a0a', '#7f240c', '#7f2e0e', '#7f3810', '#7f4212', '#7f4c14', '#7f5616', '#7f6018')), # ('darkorange-yellow', ('#7f6018', '#7e6316', '#7d6714', '#7c6b12', '#7b6f10', '#7a730e', '#79770c', '#787b0a', '#777f08')), # ('darkyellow-green', ('#777f08', '#697c09', '#5b790a', '#4d750b', '#3f720c', '#316f0d', '#236c0e', '#15690f', '#086610')), # ('darkgreen-blue', ('#086610', '#095a1d', '#0a4e2b', '#0b4239', '#0c3747', '#0d2b55', '#0e1f63', '#0f1371', '#10087f')), # ('darkblue-cyan', ('#10087f', '#10157f', '#10237f', '#10317f', '#103f7f', '#104d7f', '#105b7f', '#10697f', '#10777f')), # ('darkblue-purple', ('#10087f', '#1c097f', '#290a7f', '#360b7f', '#430c7f', '#500d7f', '#5d0e7f', '#6a0f7f', '#77107f')), # ('darkorange-red', ('#7f6018', '#7f5616', '#7f4c14', '#7f4212', '#7f3810', '#7f2e0e', '#7f240c', '#7f1a0a', '#7f1008')), # ('darkyellow-orange', ('#777f08', '#787b0a', '#79770c', '#7a730e', '#7b6f10', '#7c6b12', '#7d6714', '#7e6316', '#7f6018')), # ('darkgreen-yellow', ('#086610', '#15690f', '#236c0e', '#316f0d', '#3f720c', '#4d750b', '#5b790a', '#697c09', '#777f08')), # ('darkblue-green', ('#10087f', '#0f1371', '#0e1f63', '#0d2b55', '#0c3747', '#0b4239', '#0a4e2b', '#095a1d', '#086610')), # ('darkcyan-blue', ('#10777f', '#10697f', '#105b7f', '#104d7f', '#103f7f', '#10317f', '#10237f', '#10157f', '#10087f')), # ('darkpurple-blue', ('#77107f', '#6a0f7f', '#5d0e7f', '#500d7f', '#430c7f', '#360b7f', '#290a7f', '#1c097f', '#10087f')), # # ('darkspectrum', ( # '#008080', '#DA70D6', '#800080', '#808000', '#1E90FF', '#FFA500', '#FF0000', '#4682B4', '#008000', '#8A2BE2', '#800000', # '#00CED1', '#000080', '#FF4500', '#FF1493', '#32CD32')), # ('darkspectrum2', ( # '#32CD32', '#FF1493', '#FF4500', '#000080', '#00CED1', '#800000', '#8A2BE2', '#008000', '#4682B4', '#FF0000', '#FFA500', # '#1E90FF', '#808000', '#800080', '#DA70D6', '#008080')),