plot.py - libzahl - big integer library | |
git clone git://git.suckless.org/libzahl | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
plot.py (4192B) | |
--- | |
1 #!/usr/bin/env python3 | |
2 # See LICENSE file for copyright and license details. | |
3 | |
4 | |
5 # Invoke using `env XKCD_STYLE=` to for more a comical plot style. | |
6 | |
7 # Invoke using `env PER_BIT=` to divide all time values by the number | |
8 # of bits that where processed. This applies to 2-dimensional data only. | |
9 | |
10 # Invoke using `env VIOLIN_STYLE=` to draw violin plots rather than | |
11 # box plots. This applies to multisample 1-dimensional data only. | |
12 # If used, used `env SHOW_MEAN=` will show that mean value in place | |
13 # of the median value. | |
14 | |
15 # For multisample 1-dimensional, if `env VIOLIN_STYLE=` is not used | |
16 # `env NOTCH_STYLE=`, `env PATCH_ARTIST`, and `env SHOW_MEAN` may be | |
17 # applied. | |
18 | |
19 | |
20 import sys, os | |
21 import matplotlib.pyplot as plot | |
22 | |
23 xkcdstyle = 'XKCD_STYLE' in os.environ | |
24 if xkcdstyle: | |
25 plot.xkcd() | |
26 fig = plot.figure() | |
27 | |
28 xint = lambda x : (float(x) if '.' in x else int(x)) | |
29 | |
30 multiple = 1 | |
31 smultiple = '' | |
32 | |
33 multiples = [1] * len(sys.argv[1:]) | |
34 smultiples = [''] * len(sys.argv[1:]) | |
35 paths = [None] * len(sys.argv[1:]) | |
36 | |
37 i = 0 | |
38 for arg in sys.argv[1:]: | |
39 if arg.startswith('*'): | |
40 multiples[i] = float(arg[1:]) | |
41 smultiples[i] = ' * ' + arg[1:] | |
42 else: | |
43 paths[i] = arg | |
44 i += 1 | |
45 | |
46 multiples = multiples[:i] | |
47 smultiples = smultiples[:i] | |
48 paths = paths[:i] | |
49 | |
50 xpoints = [None] * i | |
51 ypoints = [None] * i | |
52 values = [None] * i | |
53 labels = [None] * i | |
54 | |
55 for i, path in enumerate(paths): | |
56 with open(path, 'rb') as file: | |
57 lines = file.read() | |
58 lines = lines.decode('utf-8', 'strict').split('\n') | |
59 labels[i], dim, values[i] = lines[0] + smultiples[i], int(lines[1]),… | |
60 if dim > 1: | |
61 xpoints[i], values[i] = values[i][0], values[i][1:] | |
62 xpoints[i] = [int(x) for x in xpoints[i].split(' ')] | |
63 xpoints[i][1] += 1 | |
64 xpoints[i] = list(range(*xpoints[i])) | |
65 if dim > 2: | |
66 ypoints[i], values[i] = values[i][0], values[i][1:] | |
67 ypoints[i] = [int(x) for x in ypoints[i].split(' ')] | |
68 ypoints[i][1] += 1 | |
69 ypoints[i] = list(range(*ypoints[i])) | |
70 values[i] = [xint(v) * multiples[i] for v in values[i] if v != ''] | |
71 if dim == 2: | |
72 if 'PER_BIT' in os.environ: | |
73 values[i] = [y / x for y, x in zip(values[i], xpoints[i])] | |
74 | |
75 data = [[[i], (values[i], xpoints[i], ypoints[i])] for i in range(len(va… | |
76 data.sort(key = lambda x : x[1]) | |
77 merged, data = [data[0]], data[1:] | |
78 for ([i], d) in data: | |
79 if d == merged[-1][1]: | |
80 merged[-1][0].append(i) | |
81 else: | |
82 merged.append(([i], d)) | |
83 | |
84 xpoints = [xpoints[i[0]] for (i, _) in merged] | |
85 ypoints = [ypoints[i[0]] for (i, _) in merged] | |
86 values = [values[i[0]] for (i, _) in merged] | |
87 labels = [' & '.join(labels[j] for j in i) for (i, _) in merged] | |
88 | |
89 vmin = min(min(min(v) for v in values), 0) | |
90 vmax = max(max(max(v) for v in values), 0) | |
91 | |
92 if dim == 1: | |
93 plot.ylabel('time') | |
94 if len(values[0]) == 1: | |
95 plot.bar(range(len(values)), | |
96 [vs[0] for vs in values], | |
97 align = 'center', | |
98 orientation = 'vertical', | |
99 tick_label = labels) | |
100 labels = None | |
101 elif 'VIOLIN_STYLE' in os.environ: | |
102 plot.violinplot(values, | |
103 vert = True, | |
104 showmeans = 'SHOW_MEAN' in os.environ, | |
105 showmedians = 'SHOW_MEAN' not in os.environ, | |
106 showextrema = True) | |
107 else: | |
108 plot.boxplot(values, | |
109 vert = True, | |
110 notch = 'NOTCH_STYLE' in os.environ, | |
111 patch_artist = 'PATCH_ARTIST' in os.environ) | |
112 if 'SHOW_MEAN' in os.environ: | |
113 for i in range(len(values)): | |
114 mean = sum(values[i]) / len(values[i]) | |
115 plot.plot([i + 0.75, i + 1.25], [mean, mean]); | |
116 if labels is not None: | |
117 plot.setp(fig.axes, | |
118 xticks = [x + 1 for x in range(len(values))], | |
119 xticklabels = labels) | |
120 elif dim == 2: | |
121 for i in range(len(values)): | |
122 plot.plot(xpoints[i], values[i], label = labels[i]) | |
123 plot.legend(loc = 'best') | |
124 plot.xlabel('bits') | |
125 plot.ylabel('time') | |
126 elif dim == 3: | |
127 pass | |
128 | |
129 plot.ylim((vmin * 1.1, vmax * 1.1)) | |
130 | |
131 if not xkcdstyle: | |
132 plot.grid(True) | |
133 plot.show() |