"""
CorrPlot functionalities.
It comes from `corrplot.py <https://raw.githubusercontent.com/biokit/biokit/master/biokit/viz/corrplot.py>`_
which I copied here because the module does not properly work on Python 3 (import issues).
See also `biokit license <https://github.com/biokit/biokit/blob/master/LICENSE>`_.
:author: Thomas Cokelaer
:references: http://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html
:githublink:`%|py|12`
"""
import numpy as np
[docs]class Color:
"""
Lists of known colors.
:githublink:`%|py|18`
"""
colors = {
'red': (1., 0., 0.),
'green': (0., 1., 0.),
'blue': (0., 0., 1.),
'white': (1., 1., 1.),
'black': (0., 0., 0.),
'darkblue': '#00008b',
}
[docs] def __init__(self, name):
"""
:param name: hexadecimal or name
:githublink:`%|py|32`
"""
if len(name) == 7 and name[0] == '#':
self.set_hex(name)
else:
value = Color.colors.get(name, None)
if value is None:
raise ValueError("Unknown color name '{}'.".format(name))
if len(value) == 7:
self.set_hex(value)
else:
self.red, self.green, self.blue = value
[docs] def set_hex(self, name):
"""
Converts a string like ``#AABBCC`` into `(red, green, blue)`.
:githublink:`%|py|47`
"""
self.red = float.fromhex('0x' + name[1:3].lower()) / 255
self.green = float.fromhex('0x' + name[3:5].lower()) / 255
self.blue = float.fromhex('0x' + name[5:7].lower()) / 255
[docs]class Colormap:
"""
Snippets of code from `colormap/colors.py
<https://github.com/cokelaer/colormap/blob/master/src/colormap/colors.py>`_,
`LICENSE <https://github.com/cokelaer/colormap/blob/master/LICENSE>`_.
:githublink:`%|py|58`
"""
# Source:
[docs] def _get_colormap_mpl(self):
try:
from matplotlib.pyplot import colormaps as _cmaps
return _cmaps()
except ImportError: # pragma: no cover
return []
colormaps = property(_get_colormap_mpl)
[docs] 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)']
diverging_black = property(_get_diverging_black)
[docs] def cmap_linear(self, color1, color2, color3, reverse=False, N=256):
"""
Provides 3 colors in format accepted by :class:`Color <pyensae.graphhelper._colormap.Color>`
::
red = Color('red')
cmap = cmap_linear(red, 'white', '#0000FF')
:githublink:`%|py|80`
"""
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]}
return self.cmap(dico, reverse=reverse, N=N)
[docs] def cmap(self, colors=None, reverse=False, N=256):
"""
Returns a colormap object to be used within matplotlib
:param dict colors: a dictionary that defines the RGB colors to be
used in the colormap. See :meth:`get_cmap_heat` for an example.
:param bool reverse: reverse the colormap is set to True (defaults to False)
:param int N: Defaults to 50
:githublink:`%|py|97`
"""
# matplotlib colormaps
if colors in self.colormaps:
if reverse and colors.endswith("_r") is False:
colors += "_r"
from matplotlib.cm import get_cmap
return get_cmap(colors)
# custom ones
if colors in self.diverging_black:
c1, c2, c3 = colors.split("_")
# special case of sky, which does not exists
c3 = c3.replace("sky", "deep sky blue")
return self.cmap_linear(c1, c2, c3)
if colors == 'heat':
return self.get_cmap_heat()
if colors == 'heat_r':
return self.get_cmap_heat_r()
if reverse:
for k in colors.keys():
colors[k].reverse()
# If index not given, RGB colors are evenly-spaced in colormap.
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()))
import matplotlib.colors
m = matplotlib.colors.LinearSegmentedColormap(
'my_color_map', color_data, N)
return m
[docs]def cmap_builder(name, name2=None, name3=None):
"""
Returns 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
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
being the **name2**.
Matplotlib colormap map names
Source: `colormap/get_cmap.py
<https://github.com/cokelaer/colormap/blob/master/src/colormap/get_cmap.py>`_,
`LICENSE <https://github.com/cokelaer/colormap/blob/master/LICENSE>`_).
:githublink:`%|py|145`
"""
c = Colormap()
# an R colormap
if name and name2 and name3:
return c.cmap_linear(name, name2, name3)
if name and name2:
return c.cmap_bicolor(name, name2)
if name == 'heat':
return c.get_cmap_heat()
if name == 'heat_r':
return c.get_cmap_heat_r()
# matplotlic colormaps
if name in c.colormaps:
return c.cmap(name)
# some custom diverging colormaps with black in the middle.
if name in c.diverging_black:
return c.cmap(name)
if name.count("_") == 2:
name1, name2, name3 = name.split("_")
return c.cmap_linear(name1, name2, name3)
# 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)