plot.py - libzahl - big integer library
(HTM) git clone git://git.suckless.org/libzahl
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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]), lines[2:]
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(values))]
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()