diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f08b6f9..27c93bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,21 +23,20 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - + - name: Install the package itself run: | pip install --upgrade pip - pip install -r requirements.txt pip install . pip install pytest pytest-cov coveralls pytest-xdist pytest-timeout - + - name: Test with pytest run: | pytest --cov-report term --cov=colormap - - - name: coveralls + + - name: coveralls run: | coveralls --service=github env: GITHUB_TOKEN: ${{ github.token }} - + diff --git a/MANIFEST.in b/MANIFEST.in index 9d5d250..1bd8c96 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,5 @@ include LICENSE include README.rst +recursive-exclude * __pycache__ +recursive-exclude * *pyc +include requirements*txt diff --git a/README.rst b/README.rst index 4734b3e..66ddc38 100644 --- a/README.rst +++ b/README.rst @@ -10,12 +10,12 @@ Please see : http://colormap.readthedocs.io/ for an up-to-date documentation. .. image:: https://github.com/cokelaer/colormap/actions/workflows/ci.yml/badge.svg?branch=master :target: https://github.com/cokelaer/colormap/actions/workflows/ci.yml - + .. image:: https://coveralls.io/repos/cokelaer/colormap/badge.png?branch=master :target: https://coveralls.io/r/cokelaer/colormap?branch=master -:version: Python 3.6, 3.7, 3.8, 3.9 +:version: Python 3.7, 3.8, 3.9, 3.10 :contributions: Please join https://github.com/cokelaer/colormap :issues: Please use https://github.com/cokelaer/colormap/issues :notebook: Please see https://github.com/cokelaer/colormap/tree/master/notebooks @@ -69,3 +69,15 @@ Example :align: center See online documentation for details: http://colormap.readthedocs.io/ + +changelog +######### + +========= ================================================================================ +Version Description +========= ================================================================================ +1.0.5 * remove Python3.6 and added Python3.10 to CI action + * Fix issue in setup reported in https://github.com/cokelaer/colormap/pull/14 + * add requirements in MANIFEST + * applied black on all files +========= ================================================================================ diff --git a/setup.py b/setup.py index a64064d..ef0c64d 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ _MAJOR = 1 _MINOR = 0 -_MICRO = 4 +_MICRO = 5 version = '%d.%d.%d' % (_MAJOR, _MINOR, _MICRO) release = '%d.%d' % (_MAJOR, _MINOR) @@ -27,21 +27,21 @@ 'Intended Audience :: Science/Research', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Software Development :: Libraries :: Python Modules' ] } on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if on_rtd is True: # only import and set the theme if we're building docs - install_requires = ['matplotlib', 'easydev', "numpydoc"] -else: - install_requires = ['matplotlib', 'easydev'] +with open("requirements.txt", "r") as fin: + install_requires = fin.read().split() +if on_rtd is True: # only import and set the theme if we're building docs + install_requires += ["numpydoc"] setup( @@ -65,7 +65,3 @@ packages = ['colormap'], install_requires = install_requires, ) - - - - diff --git a/src/colormap/__init__.py b/src/colormap/__init__.py index 0266932..f30e680 100644 --- a/src/colormap/__init__.py +++ b/src/colormap/__init__.py @@ -20,11 +20,12 @@ from __future__ import division import pkg_resources + try: - version = pkg_resources.require("colormap")[0].version - __version__ = version + version = pkg_resources.require("colormap")[0].version + __version__ = version except Exception: - version = '' + version = "" from .xfree86 import * diff --git a/src/colormap/colors.py b/src/colormap/colors.py index a765fbb..6671d16 100644 --- a/src/colormap/colors.py +++ b/src/colormap/colors.py @@ -27,10 +27,25 @@ from colormap.xfree86 import XFree86_colors -__all__ = ["HEX", "Color", "hex2web", "web2hex", "hex2rgb", "hex2dec", - "rgb2hex", "rgb2hsv", "hsv2rgb", "rgb2hls", "hls2rgb","yuv2rgb", "rgb2yuv", - "to_intensity", "yuv2rgb_int", "rgb2yuv_int", "Colormap" - ] +__all__ = [ + "HEX", + "Color", + "hex2web", + "web2hex", + "hex2rgb", + "hex2dec", + "rgb2hex", + "rgb2hsv", + "hsv2rgb", + "rgb2hls", + "hls2rgb", + "yuv2rgb", + "rgb2yuv", + "to_intensity", + "yuv2rgb_int", + "rgb2yuv_int", + "Colormap", +] def hex2web(hexa): @@ -91,7 +106,7 @@ def hex2rgb(hexcolor, normalise=False): :func:`hls2rgb` """ hexcolor = HEX().get_standard_hex_color(hexcolor)[1:] - r, g, b = int(hexcolor[0:2], 16), int(hexcolor[2:4], 16), int(hexcolor[4:6], 16) + r, g, b = int(hexcolor[0:2], 16), int(hexcolor[2:4], 16), int(hexcolor[4:6], 16) if normalise: r, g, b = _normalise(r, g, b) return r, g, b @@ -124,7 +139,7 @@ def rgb2hex(r, g, b, normalised=False): check_range(r, 0, 255) check_range(g, 0, 255) check_range(b, 0, 255) - return '#%02X%02X%02X' % (r, g, b) + return "#%02X%02X%02X" % (r, g, b) def rgb2hls(r, g, b, normalised=True): @@ -155,7 +170,7 @@ def rgb2hls(r, g, b, normalised=True): check_range(r, 0, upper) check_range(g, 0, upper) check_range(b, 0, upper) - if normalised==False: + if normalised == False: r, g, b = _normalise(r, g, b) h, l, s = colorsys.rgb_to_hls(r, g, b) return h, l, s @@ -189,10 +204,10 @@ def rgb2hsv(r, g, b, normalised=True): check_range(r, 0, upper) check_range(g, 0, upper) check_range(b, 0, upper) - if normalised==False: + if normalised == False: r, g, b = _normalise(r, g, b) h, s, v = colorsys.rgb_to_hsv(r, g, b) - return h,s,v + return h, s, v def hsv2rgb(h, s, v, normalised=True): @@ -271,9 +286,10 @@ def hls2rgb(h, l, s, normalised=True): def hex2dec(data): """convert hexadecimal string (data) into a float in the [0-65536] inclusive range""" - if data[0] == '#': - data.replace('#', '') - return int(data, 16)/255. + if data[0] == "#": + data.replace("#", "") + return int(data, 16) / 255.0 + def rgb2yuv(r, g, b): """Convert RGB triplet into YUV @@ -289,13 +305,13 @@ def rgb2yuv(r, g, b): check_range(g, 0, 1) check_range(b, 0, 1) - #y = int(0.299 * r + 0.587 * g + 0.114 * b) - #u = int(-0.14713 * r + -0.28886 * g + 0.436 * b) - #v = int(0.615 * r + -0.51499 * g + -0.10001 * b) + # y = int(0.299 * r + 0.587 * g + 0.114 * b) + # u = int(-0.14713 * r + -0.28886 * g + 0.436 * b) + # v = int(0.615 * r + -0.51499 * g + -0.10001 * b) y = 0.299 * r + 0.587 * g + 0.114 * b - u = -32591.0/221500.0 * r + -63983.0/221500.0 * g + 0.436 * b - v = 0.615 * r + -72201./140200 * g + -7011/70100. * b + u = -32591.0 / 221500.0 * r + -63983.0 / 221500.0 * g + 0.436 * b + v = 0.615 * r + -72201.0 / 140200 * g + -7011 / 70100.0 * b return (y, u, v) @@ -307,10 +323,10 @@ def yuv2rgb(y, u, v): .. warning:: expected input must be between 0 and 255 (not normalised) """ - check_range(y, 0,1) + check_range(y, 0, 1) check_range(u, 0, 1) check_range(v, 0, 1) - A, B, C, D = 701.0/615.0, 25251.0/63983.0, 209599.0/361005.0, 443.0/218.0 + A, B, C, D = 701.0 / 615.0, 25251.0 / 63983.0, 209599.0 / 361005.0, 443.0 / 218.0 r = y + A * v g = y - B * u - C * v b = y + D * u @@ -330,8 +346,8 @@ def rgb2yuv_int(r, g, b): check_range(b, 0, 255) y = int(0.299 * r + 0.587 * g + 0.114 * b) - u = int(-32591.0/221500.0 * r + -63983.0/221500.0 * g + 0.436 * b) - v = int(0.615 * r + -72201./140200 * g + -7011/70100. * b) + u = int(-32591.0 / 221500.0 * r + -63983.0 / 221500.0 * g + 0.436 * b) + v = int(0.615 * r + -72201.0 / 140200 * g + -7011 / 70100.0 * b) return (y, u, v) @@ -356,17 +372,17 @@ def yuv2rgb_int(y, u, v): def _denormalise(r, g, b, mode="rgb"): check_param_in_list(mode, ["rgb", "hls", "hsv"]) if mode == "rgb": - return r*255., g*255., b*255. + return r * 255.0, g * 255.0, b * 255.0 elif mode in ["hls", "hsv"]: - return r*360., g*100., b*100. + return r * 360.0, g * 100.0, b * 100.0 def _normalise(r, g, b, mode="rgb"): check_param_in_list(mode, ["rgb", "hls", "hsv"]) if mode == "rgb": - return r/255., g/255., b/255. + return r / 255.0, g / 255.0, b / 255.0 elif mode in ["hls", "hsv"]: - return r/360., g/100., b/100. + return r / 360.0, g / 100.0, b / 100.0 def to_intensity(n): @@ -391,6 +407,7 @@ class HEX(object): True """ + def __init__(self): pass @@ -418,13 +435,13 @@ def get_standard_hex_color(self, value): By standard, we mean a string that starts with # sign followed by 6 character, e.g. #AABBFF """ - if isinstance(value, str)==False: + if isinstance(value, str) == False: raise TypeError("value must be a string") if len(value) <= 3: raise ValueError("input string must be of type 0xFFF, 0xFFFFFF or #FFF or #FFFFFF") if value.startswith("0x") or value.startswith("0X"): - value = value[2:] + value = value[2:] elif value.startswith("#"): value = value[1:] else: @@ -437,9 +454,9 @@ def get_standard_hex_color(self, value): raise ValueError("Found invalid hexa character {0}".format(x)) if len(value) == 6 or len(value) == 8: - value = "#" + value[0:6] + value = "#" + value[0:6] elif len(value) == 3: - value = "#" + value[0]*2 + value[1]*2 + value[2]*2 + value = "#" + value[0] * 2 + value[1] * 2 + value[2] * 2 else: raise ValueError("hexa string should be 3, 6 or 8 digits. if 8 digits, last 2 are ignored") return value @@ -482,18 +499,19 @@ class Color(HEX): provided as "Spring Green", "spring green", "springgreen" or "SpringGreen". """ + # Get official color names colors = XFree86_colors.copy() # add color names without spaces - aliases = dict([(x.replace(" ", ""),x) for x in colors.keys() if " " in x]) + aliases = dict([(x.replace(" ", ""), x) for x in colors.keys() if " " in x]) # add color names without spaces in lower cases - aliases.update([(x.replace(" ", "").lower(),x) for x in colors.keys() if " " in x]) + aliases.update([(x.replace(" ", "").lower(), x) for x in colors.keys() if " " in x]) # add color names in lower case - aliases.update(dict([(x.lower(),x) for x in colors.keys()])) - aliases.update(dict([(x,x) for x in colors.keys()])) + aliases.update(dict([(x.lower(), x) for x in colors.keys()])) + aliases.update(dict([(x, x) for x in colors.keys()])) # keep track of all possible names - color_names = sorted(list(set(list(colors.keys()) +list( aliases.keys())))) + color_names = sorted(list(set(list(colors.keys()) + list(aliases.keys())))) def __init__(self, name=None, rgb=None, hls=None, hsv=None): super(Color, self).__init__() @@ -512,7 +530,7 @@ def __init__(self, name=None, rgb=None, hls=None, hsv=None): # if not, then, the user probably provided a valid color name # the property will check the validity. self.name = name[:] - #all other input parameters are ignored + # all other input parameters are ignored elif name == None: if rgb: self.rgb = rgb @@ -529,17 +547,20 @@ def __init__(self, name=None, rgb=None, hls=None, hsv=None): def _get_name(self): return self._name + def _set_name(self, name): check_param_in_list(name, self.color_names) name = self.aliases[name] self._name = name # set hex and rgb at the same time based on the name self.hex = self.colors[name] + name = property(_get_name, _set_name) color = property(_get_name, _set_name) def _get_hex(self): return self._hex + def _set_hex(self, value): # hex is an approximation made of 255 bits so do not define rgb here if self.is_valid_hex_color(value): @@ -553,109 +574,126 @@ def _set_hex(self, value): else: # just to warn the user self.get_standard_hex_color(value) - hex = property(_get_hex, _set_hex, - doc="getter/setter the hexadecimal value.") + + hex = property(_get_hex, _set_hex, doc="getter/setter the hexadecimal value.") def _get_rgb(self): return self._rgb + def _set_rgb(self, value): # set name, hex and rgb - self.hex = rgb2hex(*value , normalised=True) + self.hex = rgb2hex(*value, normalised=True) # must reset rgb with its real value (set_hex may round the rgb) # in _set_hex self._rgb = value - rgb = property(_get_rgb, _set_rgb, - doc="getter/setter the RGB values (3-length tuple)") + + rgb = property(_get_rgb, _set_rgb, doc="getter/setter the RGB values (3-length tuple)") def _get_hsv(self): hsv = rgb2hsv(*self.rgb) return hsv + def _set_hsv(self, value): # TODO: value must be normalised self.rgb = hsv2rgb(*value) - hsv = property(_get_hsv, _set_hsv, - doc="getter/setter the HSV values (3-length tuple)") + + hsv = property(_get_hsv, _set_hsv, doc="getter/setter the HSV values (3-length tuple)") def _get_hls(self): hls = rgb2hls(*self.rgb) return hls + def _set_hls(self, value): - #hls = _normalise(*value, mode="hls") - #else: + # hls = _normalise(*value, mode="hls") + # else: hls = value self.rgb = hls2rgb(*hls) - hls = property(_get_hls, _set_hls, - doc="getter/setter the HLS values (3-length tuple)") + + hls = property(_get_hls, _set_hls, doc="getter/setter the HLS values (3-length tuple)") def _get_lightness(self): return self.hls[1] + def _set_lightness(self, lightness): h, l, s = self.hls self.hls = (h, lightness, s) - lightness = property(_get_lightness, _set_lightness, - doc="getter/setter the lightness in the HLS triplet") + + lightness = property(_get_lightness, _set_lightness, doc="getter/setter the lightness in the HLS triplet") def _get_saturation_hls(self): return self.hls[2] + def _set_saturation_hls(self, saturation): h, l, s = self.hls self.hls = (h, l, saturation) - saturation_hls = property(_get_saturation_hls, _set_saturation_hls, - doc="getter/setter the saturation in the HLS triplet") + + saturation_hls = property( + _get_saturation_hls, _set_saturation_hls, doc="getter/setter the saturation in the HLS triplet" + ) def _get_hue(self): return self.hls[0] + def _set_hue(self, hue): h, l, s = self.hls self.hls = (hue, l, s) - hue = property(_get_hue, _set_hue, - doc="getter/setter the saturation in the HLS triplet") + + hue = property(_get_hue, _set_hue, doc="getter/setter the saturation in the HLS triplet") def _get_red(self): return self.rgb[0] + def _set_red(self, red): r, g, b = self.rgb - self.rgb = (red,g,b) - red = property(_get_red, _set_red, - doc="getter/setter for the red color in RGB triplet") + self.rgb = (red, g, b) + + red = property(_get_red, _set_red, doc="getter/setter for the red color in RGB triplet") def _get_green(self): return self.rgb[1] + def _set_green(self, green): r, g, b = self.rgb self.rgb = (r, green, b) - green = property(_get_green, _set_green, - doc="getter/setter for the green color in RGB triplet") + + green = property(_get_green, _set_green, doc="getter/setter for the green color in RGB triplet") def _get_blue(self): return self.rgb[2] + def _set_blue(self, blue): r, g, b = self.rgb self.rgb = (r, g, blue) - blue = property(_get_blue, _set_blue, - doc="getter/setter for the blue color in RGB triplet") + + blue = property(_get_blue, _set_blue, doc="getter/setter for the blue color in RGB triplet") def _get_value(self): return self.hls[0] + def _set_value(self, value): h, s, v = self.hsv self.hsv = (h, s, value) - value = property(_get_value, _set_value, - doc="getter/setter the value in the HSV triplet") + + value = property(_get_value, _set_value, doc="getter/setter the value in the HSV triplet") def _get_yiq(self): return colorsys.rgb_to_yiq(*self.rgb) + yiq = property(_get_yiq, doc="Getter for the YIQ triplet") def __str__(self): - txt = 'Color {0}\n'.format(self.name) - txt+= ' hexa code: {0}\n'.format(self.hex) - txt+= ' RGB code: {0}\n'.format(self.rgb) - txt+= ' RGB code (un-normalised): {0}\n\n'.format([x*255 for x in self.rgb]) - txt+= ' HSV code: {0}\n'.format(self.hsv) - txt+= ' HSV code: (un-normalised) {0} {1} {2}\n\n'.format(self.hsv[0]*360, self.hsv[1]*100, self.hsv[2]*100) - txt+= ' HLS code: {0}\n'.format(self.hls) - txt+= ' HLS code: (un-normalised) {0} {1} {2}\n\n'.format(self.hls[0]*360, self.hls[1]*100, self.hls[2]*100) + txt = "Color {0}\n".format(self.name) + txt += " hexa code: {0}\n".format(self.hex) + txt += " RGB code: {0}\n".format(self.rgb) + txt += " RGB code (un-normalised): {0}\n\n".format([x * 255 for x in self.rgb]) + txt += " HSV code: {0}\n".format(self.hsv) + txt += " HSV code: (un-normalised) {0} {1} {2}\n\n".format( + self.hsv[0] * 360, self.hsv[1] * 100, self.hsv[2] * 100 + ) + txt += " HLS code: {0}\n".format(self.hls) + txt += " HLS code: (un-normalised) {0} {1} {2}\n\n".format( + self.hls[0] * 360, self.hls[1] * 100, self.hls[2] * 100 + ) return txt @@ -693,7 +731,7 @@ class Colormap(object): cmap = c.cmap_linear("red", "white", "green") c.test_colormap(cmap) - Even simpler, you can use a bicolor colormap :meth:`cmap_bicolor`. For instance + Even simpler, you can use a bicolor colormap :meth:`cmap_bicolor`. For instance for a red to green colormap:: cmap = c.cmap_bicolor("red", "green") @@ -713,46 +751,116 @@ class Colormap(object): :references: matplotlib documentation and examples http://matplotlib.org/examples/color/colormaps_reference.html """ + def _get_colormap_mpl(self): try: from matplotlib.pyplot import colormaps as _cmaps + return _cmaps() except: return [] + colormaps = property(_get_colormap_mpl) def _get_sequentials(self): - return ['Blues', 'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'OrRd', - 'Oranges', 'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu', - 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd'] + return [ + "Blues", + "BuGn", + "BuPu", + "GnBu", + "Greens", + "Greys", + "OrRd", + "Oranges", + "PuBu", + "PuBuGn", + "PuRd", + "Purples", + "RdPu", + "Reds", + "YlGn", + "YlGnBu", + "YlOrBr", + "YlOrRd", + ] + sequentials = property(_get_sequentials) def _get_sequentials2(self): - return ['afmhot', 'autumn', 'bone', 'cool', 'copper', - 'gist_heat', 'gray', 'hot', 'pink', - 'spring', 'summer', 'winter'] + return [ + "afmhot", + "autumn", + "bone", + "cool", + "copper", + "gist_heat", + "gray", + "hot", + "pink", + "spring", + "summer", + "winter", + ] + sequentials2 = property(_get_sequentials2) def _get_diverging(self): - return ['BrBG', 'PRGn', 'PiYG', 'PuOr', 'RdBu', 'RdGy', 'RdYlBu', - 'RdYlGn', 'Spectral', 'bwr', 'coolwarm', 'seismic'] + return [ + "BrBG", + "PRGn", + "PiYG", + "PuOr", + "RdBu", + "RdGy", + "RdYlBu", + "RdYlGn", + "Spectral", + "bwr", + "coolwarm", + "seismic", + ] + diverging = property(_get_diverging) def _get_diverging_black(self): - return ['red_black_sky', 'red_black_blue', 'red_black_green', 'yellow_black_blue', - 'yellow_black_sky', 'red_black_orange', 'pink_black_green(w3c)' - ] + return [ + "red_black_sky", + "red_black_blue", + "red_black_green", + "yellow_black_blue", + "yellow_black_sky", + "red_black_orange", + "pink_black_green(w3c)", + ] + diverging_black = property(_get_diverging_black) def _get_qualitative(self): - return ['Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', - 'Set1', 'Set2', 'Set3'] + return ["Accent", "Dark2", "Paired", "Pastel1", "Pastel2", "Set1", "Set2", "Set3"] + qualitative = property(_get_qualitative) def _get_misc(self): - return ['gist_earth', 'terrain', 'ocean', 'gist_stern', - 'brg', 'CMRmap', 'cubehelix', 'gnuplot', 'gnuplot2', 'gist_ncar', - 'nipy_spectral', 'jet', 'rainbow', 'gist_rainbow', 'hsv', 'flag', 'prism'] + return [ + "gist_earth", + "terrain", + "ocean", + "gist_stern", + "brg", + "CMRmap", + "cubehelix", + "gnuplot", + "gnuplot2", + "gist_ncar", + "nipy_spectral", + "jet", + "rainbow", + "gist_rainbow", + "hsv", + "flag", + "prism", + ] + misc = property(_get_misc) def plot_rgb_from_hex_list(self, cols): @@ -775,14 +883,15 @@ def plot_rgb_from_hex_list(self, cols): """ import pylab - red = [hex2rgb(x)[0]/255. for x in cols] - blue = [hex2rgb(x)[2]/255. for x in cols] - green = [hex2rgb(x)[1]/255. for x in cols] + + red = [hex2rgb(x)[0] / 255.0 for x in cols] + blue = [hex2rgb(x)[2] / 255.0 for x in cols] + green = [hex2rgb(x)[1] / 255.0 for x in cols] x = pylab.linspace(0, 1, len(cols)) pylab.clf() - pylab.plot(x, red, 'ro-', alpha=0.5) - pylab.plot(x, green, 'gs-', alpha=0.5, markersize=15) - pylab.plot(x, blue, 'bx-', alpha=0.5, markersize=15) + pylab.plot(x, red, "ro-", alpha=0.5) + pylab.plot(x, green, "gs-", alpha=0.5, markersize=15) + pylab.plot(x, blue, "bx-", alpha=0.5, markersize=15) pylab.ylim([-0.1, 1.1]) def cmap_bicolor(self, color1, color2, reverse=False, N=256): @@ -797,9 +906,7 @@ def cmap_bicolor(self, color1, color2, reverse=False, N=256): """ c1 = Color(color1) c2 = Color(color2) - dico = {'red': [c1.red, c2.red], - 'green':[c1.green, c2.green], - 'blue':[c1.blue, c2.blue]} + dico = {"red": [c1.red, c2.red], "green": [c1.green, c2.green], "blue": [c1.blue, c2.blue]} return self.cmap(dico, reverse=reverse, N=N) def cmap_linear(self, color1, color2, color3, reverse=False, N=256): @@ -814,9 +921,11 @@ def cmap_linear(self, color1, color2, color3, reverse=False, N=256): c1 = Color(color1) c2 = Color(color2) c3 = Color(color3) - dico = {'red': [c1.red, c2.red, c3.red], - 'green':[c1.green, c2.green, c3.green], - 'blue':[c1.blue, c2.blue, c3.blue]} + dico = { + "red": [c1.red, c2.red, c3.red], + "green": [c1.green, c2.green, c3.green], + "blue": [c1.blue, c2.blue, c3.blue], + } return self.cmap(dico, reverse=reverse, N=N) @@ -834,6 +943,7 @@ def cmap(self, colors=None, reverse=False, N=256): if reverse and colors.endswith("_r") is False: colors += "_r" from matplotlib.cm import get_cmap + return get_cmap(colors) # custom ones elif colors in self.diverging_black: @@ -841,16 +951,16 @@ def cmap(self, colors=None, reverse=False, N=256): # special case of sky, which does not exists c3 = c3.replace("sky", "deep sky blue") return self.cmap_linear(c1, c2, c3) - elif colors == 'heat': + elif colors == "heat": return self.get_cmap_heat() - elif colors == 'heat_r': + elif colors == "heat_r": return self.get_cmap_heat_r() - # Keep these dependencies inside the function to allow # installation of colormap without those dependencies # FIXME remove numpy dependencies import numpy as np + # extracted from R, heat.colors(20) if reverse: @@ -858,18 +968,17 @@ def cmap(self, colors=None, reverse=False, N=256): colors[k].reverse() # If index not given, RGB colors are evenly-spaced in colormap. - index = np.linspace(0, 1, len(colors['red'])) + index = np.linspace(0, 1, len(colors["red"])) # Adapt color_data to the form expected by LinearSegmentedColormap. - color_data = dict((key, [(x, y, y) for x, y in zip(index, value)]) - for key, value in list(colors.items())) + color_data = dict((key, [(x, y, y) for x, y in zip(index, value)]) for key, value in list(colors.items())) import matplotlib + f = matplotlib.colors.LinearSegmentedColormap - m = f('my_color_map', color_data, N) + m = f("my_color_map", color_data, N) return m - def get_cmap_heat(self): """Return a heat colormap matplotlib-compatible colormap @@ -890,19 +999,15 @@ def get_cmap_heat(self): """ return self.cmap( - { 'blue':[0, 0, 0, 0, 1], - 'green':[0, .35, .7, 1, 1], - 'red':[1, 1, 1, 1, 1]}, reverse=False) + {"blue": [0, 0, 0, 0, 1], "green": [0, 0.35, 0.7, 1, 1], "red": [1, 1, 1, 1, 1]}, reverse=False + ) def get_cmap_heat_r(self): """Return a heat colormap matplotlib-compatible colormap Same as :meth:`get_cmap_heat` but reversed """ - return self.cmap( - { 'blue':[0, 0, 0, 0, 1], - 'green':[0, .35, .7, 1, 1], - 'red':[1, 1, 1, 1, 1]}, reverse=True) + return self.cmap({"blue": [0, 0, 0, 0, 1], "green": [0, 0.35, 0.7, 1, 1], "red": [1, 1, 1, 1, 1]}, reverse=True) def get_cmap_rainbow(self): """colormap similar to rainbow colormap from R @@ -912,16 +1017,18 @@ def get_cmap_rainbow(self): """ return self.cmap( - { 'blue': [0, 0, 0, 1, 1, 1, 0], - 'green':[0, 1, 1, 1, 0, 0, 0], - 'red': [1, 1, 0, 0, 0, 1, 1]}, reverse=False) - + {"blue": [0, 0, 0, 1, 1, 1, 0], "green": [0, 1, 1, 1, 0, 0, 0], "red": [1, 1, 0, 0, 0, 1, 1]}, reverse=False + ) def get_cmap_red_green(self): return self.cmap( - { 'green': [0, 0.4, 0.6, .75, .8, .9, 1, .9, .8, .6], - 'blue' : [0, .4, .6, .75, .8, .7, .6, .35, .17, .1], - 'red': [1, 1, 1, 1, 1, .9, .8, .6, .3, .1]}, reverse=True) + { + "green": [0, 0.4, 0.6, 0.75, 0.8, 0.9, 1, 0.9, 0.8, 0.6], + "blue": [0, 0.4, 0.6, 0.75, 0.8, 0.7, 0.6, 0.35, 0.17, 0.1], + "red": [1, 1, 1, 1, 1, 0.9, 0.8, 0.6, 0.3, 0.1], + }, + reverse=True, + ) def test_colormap(self, cmap=None): """plot one colormap for testing @@ -933,12 +1040,13 @@ def test_colormap(self, cmap=None): cmap = self.get_cmap_heat() import numpy as np from pylab import clf, pcolor, colorbar, show, linspace, axis + A, B = np.meshgrid(linspace(0, 10, 100), linspace(0, 10, 100)) clf() - pcolor((A-5)**2+(B-5)**2, cmap=cmap) + pcolor((A - 5) ** 2 + (B - 5) ** 2, cmap=cmap) colorbar() show() - axis('off') + axis("off") def plot_colormap(self, cmap_list=None): """cmap_list list of valid cmap or name of a set (sequential, @@ -959,32 +1067,33 @@ def plot_colormap(self, cmap_list=None): from pylab import subplots if isinstance(cmap_list, str): - if cmap_list in ['sequentials','sequentials2','qualitative', - 'misc','diverging', 'diverging_black']: + if cmap_list in ["sequentials", "sequentials2", "qualitative", "misc", "diverging", "diverging_black"]: cmap_list = getattr(self, cmap_list) else: cmap_list = [cmap_list] if isinstance(cmap_list, list) is not True: - raise TypeError("""input must be a list of srtings or a single string. Each string should be found. For a user-defined cmap, use test_colormap""") + raise TypeError( + """input must be a list of srtings or a single string. Each string should be found. For a user-defined cmap, use test_colormap""" + ) for this in cmap_list: if this not in self.colormaps and this not in self.diverging_black: raise ValueError("unknown colormap name. Please check valid names in colormaps attribute") nrows = len(cmap_list) - gradient = [x/255. for x in range(0,256)] + gradient = [x / 255.0 for x in range(0, 256)] gradient = [gradient, gradient] - #np.vstack((gradient, gradient)) + # np.vstack((gradient, gradient)) fig, axes = subplots(nrows=nrows) fig.subplots_adjust(top=0.95, bottom=0.05, left=0.05, right=0.8) for ax, name in zip(axes, cmap_list): - ax.imshow(gradient, aspect='auto', cmap=self.cmap(name)) + ax.imshow(gradient, aspect="auto", cmap=self.cmap(name)) pos = list(ax.get_position().bounds) x_text = pos[2] + 0.08 - y_text = pos[1] + pos[3]/2. - fig.text(x_text, y_text, name, va='center', ha='left', fontsize=10) + y_text = pos[1] + pos[3] / 2.0 + fig.text(x_text, y_text, name, va="center", ha="left", fontsize=10) # Turn off *all* ticks & spines, not just the ones with colormaps. for ax in axes: diff --git a/src/colormap/get_cmap.py b/src/colormap/get_cmap.py index 6d7dbe9..83f6502 100644 --- a/src/colormap/get_cmap.py +++ b/src/colormap/get_cmap.py @@ -10,19 +10,19 @@ # See accompanying file LICENSE.txt or copy at # http://www.gnu.org/licenses/gpl-3.0.html # -# website: +# website: # ############################################################################## from colormap import Colormap -__all__ = ['cmap_builder'] +__all__ = ["cmap_builder"] def cmap_builder(name, name2=None, name3=None): """return a colormap object compatible with matplotlib - If only parameter **name** is provided, it should be a known matplotlib - colormap name (e.g., jet). If **name2** is provided, then a new colormap + If only parameter **name** is provided, it should be a known matplotlib + colormap name (e.g., jet). If **name2** is provided, then a new colormap is created going from the color **name** to the color **name2** with a linear scale. Finally, if **name3** is provided, a linear scaled colormap is built from color **name** to color **name3** with the intermediate color @@ -45,9 +45,9 @@ def cmap_builder(name, name2=None, name3=None): return c.cmap_linear(name, name2, name3) elif name and name2: return c.cmap_bicolor(name, name2) - elif name == 'heat': + elif name == "heat": return c.get_cmap_heat() - elif name == 'heat_r': + elif name == "heat_r": return c.get_cmap_heat_r() # matplotlic colormaps elif name in c.colormaps: @@ -59,8 +59,7 @@ def cmap_builder(name, name2=None, name3=None): name1, name2, name3 = name.split("_") return c.cmap_linear(name1, name2, name3) else: - #valid = c.colormaps + c.diverging_black + # valid = c.colormaps + c.diverging_black txt = "name provided {0} is not recognised. ".format(name) txt += "\n valid name can be found in colormap.colormap_names" raise ValueError(txt) - diff --git a/src/colormap/xfree86.py b/src/colormap/xfree86.py index d8d3238..1ba1340 100644 --- a/src/colormap/xfree86.py +++ b/src/colormap/xfree86.py @@ -21,153 +21,150 @@ # TC: I have added the "green" key, which is the same as green(x11) XFree86_colors = { - "Alice Blue" : "#F0F8FF", - "AliceBlue" : "#F0F8FF", - "Antique White" : "#FAEBD7", - "Aqua" : "#00FFFF", - "Aquamarine" : "#7FFFD4", - "Azure" : "#F0FFFF", - "Beige" : "#F5F5DC", - "Bisque" : "#FFE4C4", - "Black" : "#000000", - "Blanched Almond" : "#FFEBCD", - "Blue" : "#0000FF", - "Blue Violet" : "#8A2BE2", - "Brown" : "#A52A2A", - "Burlywood" : "#DEB887", - "Cadet Blue" : "#5F9EA0", - "Chartreuse" : "#7FFF00", - "Chocolate" : "#D2691E", - "Coral" : "#FF7F50", - "Cornflower" : "#6495ED", - "Cornsilk" : "#FFF8DC", - "Crimson" : "#DC143C", - "Cyan" : "#00FFFF", - "Dark Blue" : "#00008B", - "Dark Cyan" : "#008B8B", - "Dark Goldenrod" : "#B8860B", - "Dark Gray" : "#A9A9A9", - "Dark Green" : "#006400", - "Dark Khaki" : "#BDB76B", - "Dark Magenta" : "#8B008B", - "Dark Olive Green" : "#556B2F", - "Dark Orange" : "#FF8C00", - "Dark Orchid" : "#9932CC", - "Dark Red" : "#8B0000", - "Dark Salmon" : "#E9967A", - "Dark Sea Green" : "#8FBC8F", - "Dark Slate Blue" : "#483D8B", - "Dark Slate Gray" : "#2F4F4F", - "Dark Turquoise" : "#00CED1", - "Dark Violet" : "#9400D3", - "Deep Pink" : "#FF1493", - "Deep Sky Blue" : "#00BFFF", - "Dim Gray" : "#696969", - "Dodger Blue" : "#1E90FF", - "Firebrick" : "#B22222", - "Floral White" : "#FFFAF0", - "Forest Green" : "#228B22", - "Fuchsia" : "#FF00FF", - "Gainsboro" : "#DCDCDC", - "Ghost White" : "#F8F8FF", - "Gold" : "#FFD700", - "Goldenrod" : "#DAA520", - "Gray (X11)" : "#BEBEBE", - "Gray (W3C)" : "#808080", - "Green (X11)" : "#00FF00", - "Green" : "#00FF00", - "Green (W3C)" : "#008000", - "Green Yellow" : "#ADFF2F", - "Honeydew" : "#F0FFF0", - "Hot Pink" : "#FF69B4", - "Indian Red" : "#CD5C5C", - "Indigo" : "#4B0082", - "Ivory" : "#FFFFF0", - "Khaki" : "#F0E68C", - "Lavender" : "#E6E6FA", - "Lavender Blush" : "#FFF0F5", - "Lawn Green" : "#7CFC00", - "Lemon Chiffon" : "#FFFACD", - "Light Blue" : "#ADD8E6", - "Light Coral" : "#F08080", - "Light Cyan" : "#E0FFFF", - "Light Goldenrod" : "#FAFAD2", - "Light Gray" : "#D3D3D3", - "Light Green" : "#90EE90", - "Light Pink" : "#FFB6C1", - "Light Salmon" : "#FFA07A", - "Light Sea Green" : "#20B2AA", - "Light Sky Blue" : "#87CEFA", - "Light Slate Gray" : "#778899", - "Light Steel Blue" : "#B0C4DE", - "Light Yellow" : "#FFFFE0", - "Lime (W3C)" : "#00FF00", - "Lime Green" : "#32CD32", - "Linen" : "#FAF0E6", - "Magenta" : "#FF00FF", - "Maroon (X11)" : "#B03060", - "Maroon (W3C)" : "#7F0000", - "Medium Aquamarine" : "#66CDAA", - "Medium Blue" : "#0000CD", - "Medium Orchid" : "#BA55D3", - "Medium Purple" : "#9370DB", - "Medium Sea Green" : "#3CB371", - "Medium Slate Blue" : "#7B68EE", - "Medium Spring Green" : "#00FA9A", - "Medium Turquoise" : "#48D1CC", - "Medium Violet Red" : "#C71585", - "Midnight Blue" : "#191970", - "Mint Cream" : "#F5FFFA", - "Misty Rose" : "#FFE4E1", - "Moccasin" : "#FFE4B5", - "Navajo White" : "#FFDEAD", - "Navy" : "#000080", - "Old Lace" : "#FDF5E6", - "Olive" : "#808000", - "Olive Drab" : "#6B8E23", - "Orange" : "#FFA500", - "Orange Red" : "#FF4500", - "Orchid" : "#DA70D6", - "Pale Goldenrod" : "#EEE8AA", - "Pale Green" : "#98FB98", - "Pale Turquoise" : "#AFEEEE", - "Pale Violet Red" : "#DB7093", - "Papaya Whip" : "#FFEFD5", - "Peach Puff" : "#FFDAB9", - "Peru" : "#CD853F", - "Pink" : "#FFC0CB", - "Plum" : "#DDA0DD", - "Powder Blue" : "#B0E0E6", - "Purple (X11)" : "#A020F0", - "Purple (W3C)" : "#7F007F", - "Red" : "#FF0000", - "Rosy Brown" : "#BC8F8F", - "Royal Blue" : "#4169E1", - "Saddle Brown" : "#8B4513", - "Salmon" : "#FA8072", - "Sandy Brown" : "#F4A460", - "Sea Green" : "#2E8B57", - "Seashell" : "#FFF5EE", - "Sienna" : "#A0522D", - "Silver (W3C)" : "#C0C0C0", - "Sky Blue" : "#87CEEB", - "Slate Blue" : "#6A5ACD", - "Slate Gray" : "#708090", - "Snow" : "#FFFAFA", - "Spring Green" : "#00FF7F", - "Steel Blue" : "#4682B4", - "Tan" : "#D2B48C", - "Teal" : "#008080", - "Thistle" : "#D8BFD8", - "Tomato" : "#FF6347", - "Turquoise" : "#40E0D0", - "Violet" : "#EE82EE", - "Wheat" : "#F5DEB3", - "White" : "#FFFFFF", - "White Smoke" : "#F5F5F5", - "Yellow" : "#FFFF00", - "Yellow Green" : "#9ACD32"} - - - - + "Alice Blue": "#F0F8FF", + "AliceBlue": "#F0F8FF", + "Antique White": "#FAEBD7", + "Aqua": "#00FFFF", + "Aquamarine": "#7FFFD4", + "Azure": "#F0FFFF", + "Beige": "#F5F5DC", + "Bisque": "#FFE4C4", + "Black": "#000000", + "Blanched Almond": "#FFEBCD", + "Blue": "#0000FF", + "Blue Violet": "#8A2BE2", + "Brown": "#A52A2A", + "Burlywood": "#DEB887", + "Cadet Blue": "#5F9EA0", + "Chartreuse": "#7FFF00", + "Chocolate": "#D2691E", + "Coral": "#FF7F50", + "Cornflower": "#6495ED", + "Cornsilk": "#FFF8DC", + "Crimson": "#DC143C", + "Cyan": "#00FFFF", + "Dark Blue": "#00008B", + "Dark Cyan": "#008B8B", + "Dark Goldenrod": "#B8860B", + "Dark Gray": "#A9A9A9", + "Dark Green": "#006400", + "Dark Khaki": "#BDB76B", + "Dark Magenta": "#8B008B", + "Dark Olive Green": "#556B2F", + "Dark Orange": "#FF8C00", + "Dark Orchid": "#9932CC", + "Dark Red": "#8B0000", + "Dark Salmon": "#E9967A", + "Dark Sea Green": "#8FBC8F", + "Dark Slate Blue": "#483D8B", + "Dark Slate Gray": "#2F4F4F", + "Dark Turquoise": "#00CED1", + "Dark Violet": "#9400D3", + "Deep Pink": "#FF1493", + "Deep Sky Blue": "#00BFFF", + "Dim Gray": "#696969", + "Dodger Blue": "#1E90FF", + "Firebrick": "#B22222", + "Floral White": "#FFFAF0", + "Forest Green": "#228B22", + "Fuchsia": "#FF00FF", + "Gainsboro": "#DCDCDC", + "Ghost White": "#F8F8FF", + "Gold": "#FFD700", + "Goldenrod": "#DAA520", + "Gray (X11)": "#BEBEBE", + "Gray (W3C)": "#808080", + "Green (X11)": "#00FF00", + "Green": "#00FF00", + "Green (W3C)": "#008000", + "Green Yellow": "#ADFF2F", + "Honeydew": "#F0FFF0", + "Hot Pink": "#FF69B4", + "Indian Red": "#CD5C5C", + "Indigo": "#4B0082", + "Ivory": "#FFFFF0", + "Khaki": "#F0E68C", + "Lavender": "#E6E6FA", + "Lavender Blush": "#FFF0F5", + "Lawn Green": "#7CFC00", + "Lemon Chiffon": "#FFFACD", + "Light Blue": "#ADD8E6", + "Light Coral": "#F08080", + "Light Cyan": "#E0FFFF", + "Light Goldenrod": "#FAFAD2", + "Light Gray": "#D3D3D3", + "Light Green": "#90EE90", + "Light Pink": "#FFB6C1", + "Light Salmon": "#FFA07A", + "Light Sea Green": "#20B2AA", + "Light Sky Blue": "#87CEFA", + "Light Slate Gray": "#778899", + "Light Steel Blue": "#B0C4DE", + "Light Yellow": "#FFFFE0", + "Lime (W3C)": "#00FF00", + "Lime Green": "#32CD32", + "Linen": "#FAF0E6", + "Magenta": "#FF00FF", + "Maroon (X11)": "#B03060", + "Maroon (W3C)": "#7F0000", + "Medium Aquamarine": "#66CDAA", + "Medium Blue": "#0000CD", + "Medium Orchid": "#BA55D3", + "Medium Purple": "#9370DB", + "Medium Sea Green": "#3CB371", + "Medium Slate Blue": "#7B68EE", + "Medium Spring Green": "#00FA9A", + "Medium Turquoise": "#48D1CC", + "Medium Violet Red": "#C71585", + "Midnight Blue": "#191970", + "Mint Cream": "#F5FFFA", + "Misty Rose": "#FFE4E1", + "Moccasin": "#FFE4B5", + "Navajo White": "#FFDEAD", + "Navy": "#000080", + "Old Lace": "#FDF5E6", + "Olive": "#808000", + "Olive Drab": "#6B8E23", + "Orange": "#FFA500", + "Orange Red": "#FF4500", + "Orchid": "#DA70D6", + "Pale Goldenrod": "#EEE8AA", + "Pale Green": "#98FB98", + "Pale Turquoise": "#AFEEEE", + "Pale Violet Red": "#DB7093", + "Papaya Whip": "#FFEFD5", + "Peach Puff": "#FFDAB9", + "Peru": "#CD853F", + "Pink": "#FFC0CB", + "Plum": "#DDA0DD", + "Powder Blue": "#B0E0E6", + "Purple (X11)": "#A020F0", + "Purple (W3C)": "#7F007F", + "Red": "#FF0000", + "Rosy Brown": "#BC8F8F", + "Royal Blue": "#4169E1", + "Saddle Brown": "#8B4513", + "Salmon": "#FA8072", + "Sandy Brown": "#F4A460", + "Sea Green": "#2E8B57", + "Seashell": "#FFF5EE", + "Sienna": "#A0522D", + "Silver (W3C)": "#C0C0C0", + "Sky Blue": "#87CEEB", + "Slate Blue": "#6A5ACD", + "Slate Gray": "#708090", + "Snow": "#FFFAFA", + "Spring Green": "#00FF7F", + "Steel Blue": "#4682B4", + "Tan": "#D2B48C", + "Teal": "#008080", + "Thistle": "#D8BFD8", + "Tomato": "#FF6347", + "Turquoise": "#40E0D0", + "Violet": "#EE82EE", + "Wheat": "#F5DEB3", + "White": "#FFFFFF", + "White Smoke": "#F5F5F5", + "Yellow": "#FFFF00", + "Yellow Green": "#9ACD32", +}