Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief CorrPlot functionalities.
5It comes from `corrplot.py <https://raw.githubusercontent.com/biokit/biokit/master/biokit/viz/corrplot.py>`_
6which I copied here because the module does not properly work on Python 3 (import issues).
7See also `biokit license <https://github.com/biokit/biokit/blob/master/LICENSE>`_.
9:author: Thomas Cokelaer
10:references: http://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html
11"""
12import numpy as np
15class Color:
16 """
17 Lists of known colors.
18 """
20 colors = {
21 'red': (1., 0., 0.),
22 'green': (0., 1., 0.),
23 'blue': (0., 0., 1.),
24 'white': (1., 1., 1.),
25 'black': (0., 0., 0.),
26 'darkblue': '#00008b',
27 }
29 def __init__(self, name):
30 """
31 @param name hexadecimal or name
32 """
33 if len(name) == 7 and name[0] == '#':
34 self.set_hex(name)
35 else:
36 value = Color.colors.get(name, None)
37 if value is None:
38 raise ValueError("Unknown color name '{}'.".format(name))
39 if len(value) == 7:
40 self.set_hex(value)
41 else:
42 self.red, self.green, self.blue = value
44 def set_hex(self, name):
45 """
46 Converts a string like ``#AABBCC`` into `(red, green, blue)`.
47 """
48 self.red = float.fromhex('0x' + name[1:3].lower()) / 255
49 self.green = float.fromhex('0x' + name[3:5].lower()) / 255
50 self.blue = float.fromhex('0x' + name[5:7].lower()) / 255
53class Colormap:
54 """
55 Snippets of code from `colormap/colors.py
56 <https://github.com/cokelaer/colormap/blob/master/src/colormap/colors.py>`_,
57 `LICENSE <https://github.com/cokelaer/colormap/blob/master/LICENSE>`_.
58 """
59 # Source:
61 def _get_colormap_mpl(self):
62 try:
63 from matplotlib.pyplot import colormaps as _cmaps
64 return _cmaps()
65 except ImportError: # pragma: no cover
66 return []
67 colormaps = property(_get_colormap_mpl)
69 def _get_diverging_black(self):
70 return ['red_black_sky', 'red_black_blue', 'red_black_green', 'yellow_black_blue',
71 'yellow_black_sky', 'red_black_orange', 'pink_black_green(w3c)']
72 diverging_black = property(_get_diverging_black)
74 def cmap_linear(self, color1, color2, color3, reverse=False, N=256):
75 """
76 Provides 3 colors in format accepted by :class:`Color`
77 ::
78 red = Color('red')
79 cmap = cmap_linear(red, 'white', '#0000FF')
80 """
81 c1 = Color(color1)
82 c2 = Color(color2)
83 c3 = Color(color3)
84 dico = {'red': [c1.red, c2.red, c3.red],
85 'green': [c1.green, c2.green, c3.green],
86 'blue': [c1.blue, c2.blue, c3.blue]}
88 return self.cmap(dico, reverse=reverse, N=N)
90 def cmap(self, colors=None, reverse=False, N=256):
91 """
92 Returns a colormap object to be used within matplotlib
93 :param dict colors: a dictionary that defines the RGB colors to be
94 used in the colormap. See :meth:`get_cmap_heat` for an example.
95 :param bool reverse: reverse the colormap is set to True (defaults to False)
96 :param int N: Defaults to 50
97 """
98 # matplotlib colormaps
99 if colors in self.colormaps:
100 if reverse and colors.endswith("_r") is False:
101 colors += "_r"
102 from matplotlib.cm import get_cmap
103 return get_cmap(colors)
104 # custom ones
105 if colors in self.diverging_black:
106 c1, c2, c3 = colors.split("_")
107 # special case of sky, which does not exists
108 c3 = c3.replace("sky", "deep sky blue")
109 return self.cmap_linear(c1, c2, c3)
110 if colors == 'heat':
111 return self.get_cmap_heat()
112 if colors == 'heat_r':
113 return self.get_cmap_heat_r()
115 if reverse:
116 for k in colors.keys():
117 colors[k].reverse()
119 # If index not given, RGB colors are evenly-spaced in colormap.
120 index = np.linspace(0, 1, len(colors['red']))
122 # Adapt color_data to the form expected by LinearSegmentedColormap.
123 color_data = dict((key, [(x, y, y) for x, y in zip(index, value)])
124 for key, value in list(colors.items()))
126 import matplotlib.colors
127 m = matplotlib.colors.LinearSegmentedColormap(
128 'my_color_map', color_data, N)
129 return m
132def cmap_builder(name, name2=None, name3=None):
133 """
134 Returns a colormap object compatible with matplotlib
135 If only parameter **name** is provided, it should be a known matplotlib
136 colormap name (e.g., jet). If **name2** is provided, then a new colormap
137 is created going from the color **name** to the color **name2** with a
138 linear scale. Finally, if **name3** is provided, a linear scaled colormap
139 is built from color **name** to color **name3** with the intermediate color
140 being the **name2**.
141 Matplotlib colormap map names
142 Source: `colormap/get_cmap.py
143 <https://github.com/cokelaer/colormap/blob/master/src/colormap/get_cmap.py>`_,
144 `LICENSE <https://github.com/cokelaer/colormap/blob/master/LICENSE>`_).
145 """
146 c = Colormap()
147 # an R colormap
148 if name and name2 and name3:
149 return c.cmap_linear(name, name2, name3)
150 if name and name2:
151 return c.cmap_bicolor(name, name2)
152 if name == 'heat':
153 return c.get_cmap_heat()
154 if name == 'heat_r':
155 return c.get_cmap_heat_r()
156 # matplotlic colormaps
157 if name in c.colormaps:
158 return c.cmap(name)
159 # some custom diverging colormaps with black in the middle.
160 if name in c.diverging_black:
161 return c.cmap(name)
162 if name.count("_") == 2:
163 name1, name2, name3 = name.split("_")
164 return c.cmap_linear(name1, name2, name3)
166 # valid = c.colormaps + c.diverging_black
167 txt = "name provided {0} is not recognised. ".format(name)
168 txt += "\n valid name can be found in colormap.colormap_names"
169 raise ValueError(txt)