Hide keyboard shortcuts

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. 

4 

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>`_. 

8 

9:author: Thomas Cokelaer 

10:references: http://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html 

11""" 

12import numpy as np 

13 

14 

15class Color: 

16 """ 

17 Lists of known colors. 

18 """ 

19 

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 } 

28 

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 

43 

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 

51 

52 

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: 

60 

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) 

68 

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) 

73 

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

87 

88 return self.cmap(dico, reverse=reverse, N=N) 

89 

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

114 

115 if reverse: 

116 for k in colors.keys(): 

117 colors[k].reverse() 

118 

119 # If index not given, RGB colors are evenly-spaced in colormap. 

120 index = np.linspace(0, 1, len(colors['red'])) 

121 

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

125 

126 import matplotlib.colors 

127 m = matplotlib.colors.LinearSegmentedColormap( 

128 'my_color_map', color_data, N) 

129 return m 

130 

131 

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) 

165 

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)