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 Plotting helpers 

4""" 

5import numpy 

6from ..benchmark import enumerate_options 

7 

8 

9def list_col_options(df, cols): 

10 """ 

11 @param df dataframe 

12 @param cols cols to look for options 

13 @return options 

14 

15 .. exref:: 

16 :title: Enumerate all coordinates 

17 

18 .. runpython:: 

19 :showcode: 

20 

21 from pymlbenchmark.plotting.plot_helper import list_col_options 

22 from pandas import DataFrame 

23 df = DataFrame([ 

24 dict(i=1, t='aa', x=0.5), 

25 dict(i=2, t='bb', x=0.5), 

26 dict(i=2, t='aa', x=0.5), 

27 ]) 

28 for opt in list_col_options(df, ['i', 't']): 

29 print(opt) 

30 

31 # if None... 

32 print(list_col_options(df, None)) 

33 """ 

34 if cols is None: 

35 return [None] 

36 

37 if not isinstance(cols, (tuple, list)): 

38 cols = [cols] 

39 elif cols[0] is None: 

40 return [None] 

41 

42 options = {k: list(sorted(set(df[k]))) for k in cols} 

43 return list(enumerate_options(options)) 

44 

45 

46def filter_df_options(df, options): 

47 """ 

48 Filters out rows from a dataframe. 

49 

50 @param df dataframe 

51 @param options options 

52 @return filtered dataframe 

53 

54 .. runpython:: 

55 :showcode: 

56 

57 from pymlbenchmark.plotting.plot_helper import filter_df_options 

58 from pandas import DataFrame 

59 df = DataFrame([ 

60 dict(i=1, t='aa', x=0.5), 

61 dict(i=2, t='bb', x=0.5), 

62 dict(i=2, t='aa', x=0.5), 

63 ]) 

64 

65 sub = filter_df_options(df, {'i': 1, 't': 'aa'}) 

66 print(sub) 

67 

68 sub = filter_df_options(df, [None]) 

69 print(sub) 

70 """ 

71 if options is None: 

72 return df 

73 elif isinstance(options, list): 

74 if options[0] is None: 

75 return df 

76 else: 

77 raise RuntimeError( # pragma: no cover 

78 "options must be dictionary or [None] not {}".format(options)) 

79 for k, v in options.items(): 

80 df = df[df[k] == v] 

81 return df 

82 

83 

84def options2label(opt, sep=" ", format_number="{:.3g}"): 

85 """ 

86 Converts a list of options into a label. 

87 

88 @param opt dictionary 

89 @param sep separator 

90 @param format_number how to format real numbers 

91 @return string 

92 

93 .. runpython:: 

94 :showcode: 

95 

96 from pymlbenchmark.plotting.plot_helper import options2label 

97 res = options2label({'i': 1, 't': 'aa', 'x': 3.145667e10}) 

98 print(res) 

99 """ 

100 if opt is None: 

101 return "-" 

102 rows = [] 

103 for k, v in sorted(opt.items()): 

104 if isinstance(v, (float, numpy.float64, numpy.float32)): 

105 v = format_number.format(v) 

106 rows.append("{}={}".format(k, v)) 

107 return sep.join(rows) 

108 

109 

110def ax_position(shape, pos): 

111 """ 

112 :epkg:`matplotlib` uses a one dimension 

113 array if the number of columns or rows is 1. 

114 This function makes a correction. 

115 

116 @param shape graph shape 

117 @param pos graph current position 

118 @return corrected position 

119 

120 .. runpython:: 

121 :showcode: 

122 

123 from pymlbenchmark.plotting.plot_helper import ax_position 

124 print(ax_position((2, 2), (0, 0))) 

125 print(ax_position((1, 2), (0, 0))) 

126 """ 

127 res = [] 

128 for a, b in zip(shape, pos): 

129 if a > 1: 

130 res.append(b) 

131 return tuple(res) 

132 

133 

134def plt_colors(): 

135 """ 

136 Returns :epkg:`matplotlib` colors. 

137 

138 .. runpython:: 

139 :showcode: 

140 

141 from pymlbenchmark.plotting.plot_helper import plt_colors 

142 from pprint import pprint 

143 pprint(plt_colors()) 

144 """ 

145 import matplotlib.colors as mcolors # pylint: disable=C0415 

146 colors = [k.split(':')[-1] for k in mcolors.TABLEAU_COLORS] 

147 for k in sorted(mcolors.CSS4_COLORS): 

148 colors.append(k) 

149 return colors 

150 

151 

152def plt_styles(): 

153 """ 

154 Returns :epkg:`matplotlib` styles. 

155 

156 .. runpython:: 

157 :showcode: 

158 

159 from pymlbenchmark.plotting.plot_helper import plt_styles 

160 from pprint import pprint 

161 pprint(plt_styles()) 

162 """ 

163 return [('o', '-'), ('x', '-'), ('*', '-'), ('^', '-'), 

164 ('o', '--'), ('x', '--'), ('*', '--'), ('^', '--')] 

165 

166 

167def move_color_add(style): 

168 """ 

169 Makes color lighter or darker 

170 based on a style. 

171 """ 

172 return {'o': 0, 'x': 80, '*': -80, '^': 120}[style] 

173 

174 

175def move_color(color, add=2): 

176 """ 

177 Returns a different colors, lighter or darker. 

178 

179 @param color name of something starting with ``#`` 

180 @param add what to add to each color, 

181 positive to make it lighter 

182 @return lighter column 

183 """ 

184 if not color.startswith("#"): 

185 import matplotlib.colors as mcolors # pylint: disable=C0415 

186 color = mcolors.CSS4_COLORS[color] 

187 rgb = tuple(int(color[1 + i * 2: 3 + i * 2], base=16) for i in range(0, 3)) 

188 if add > 0: 

189 rgb = tuple(min(255, i + add) for i in rgb) 

190 else: 

191 rgb = tuple(max(0, i + add) for i in rgb) 

192 return "#%02X%02X%02X" % rgb 

193 

194 

195def remove_common_prefix(labels, drop_rename=None): 

196 """ 

197 Removes the common prefix of a series of labels. 

198 

199 @param labels labels 

200 @param drop_rename skips those labels 

201 @return stripped labels 

202 

203 .. runpython:: 

204 :showcode: 

205 

206 from pymlbenchmark.plotting.plot_helper import remove_common_prefix 

207 labels = ["x=a", "x=b"] 

208 print(remove_common_prefix(labels)) 

209 """ 

210 drop_rename = set(drop_rename) if drop_rename else [] 

211 prefix = None 

212 for label in labels: 

213 if label in drop_rename: 

214 continue 

215 if not isinstance(label, str): 

216 if isinstance(label, float) and numpy.isnan(label): 

217 continue 

218 return labels 

219 if prefix is None: 

220 prefix = label 

221 elif not label.startswith(prefix): 

222 begin = min(len(prefix), len(label)) 

223 for i in range(begin, -1, -1): 

224 prefix = prefix[:i] # pylint: disable=E1136 

225 if label.startswith(prefix): 

226 break 

227 if prefix == "": 

228 return labels 

229 last = len(prefix) 

230 res = [(label[last:] if (isinstance(label, str) and 

231 label not in drop_rename) else label) 

232 for label in labels] 

233 return res