]> git.proxmox.com Git - mirror_novnc.git/blob - utils/json2graph.py
feat: add French localization strings
[mirror_novnc.git] / utils / json2graph.py
1 #!/usr/bin/env python
2
3 '''
4 Use matplotlib to generate performance charts
5 Copyright 2011 Joel Martin
6 Licensed under MPL-2.0 (see docs/LICENSE.MPL-2.0)
7 '''
8
9 # a bar plot with errorbars
10 import sys, json
11 import numpy as np
12 import matplotlib.pyplot as plt
13 from matplotlib.font_manager import FontProperties
14
15 def usage():
16 print "%s json_file level1 level2 level3 [legend_height]\n\n" % sys.argv[0]
17 print "Description:\n"
18 print "level1, level2, and level3 are one each of the following:\n";
19 print " select=ITEM - select only ITEM at this level";
20 print " bar - each item on this level becomes a graph bar";
21 print " group - items on this level become groups of bars";
22 print "\n";
23 print "json_file is a file containing json data in the following format:\n"
24 print ' {';
25 print ' "conf": {';
26 print ' "order_l1": [';
27 print ' "level1_label1",';
28 print ' "level1_label2",';
29 print ' ...';
30 print ' ],';
31 print ' "order_l2": [';
32 print ' "level2_label1",';
33 print ' "level2_label2",';
34 print ' ...';
35 print ' ],';
36 print ' "order_l3": [';
37 print ' "level3_label1",';
38 print ' "level3_label2",';
39 print ' ...';
40 print ' ]';
41 print ' },';
42 print ' "stats": {';
43 print ' "level1_label1": {';
44 print ' "level2_label1": {';
45 print ' "level3_label1": [val1, val2, val3],';
46 print ' "level3_label2": [val1, val2, val3],';
47 print ' ...';
48 print ' },';
49 print ' "level2_label2": {';
50 print ' ...';
51 print ' },';
52 print ' },';
53 print ' "level1_label2": {';
54 print ' ...';
55 print ' },';
56 print ' ...';
57 print ' },';
58 print ' }';
59 sys.exit(2)
60
61 def error(msg):
62 print msg
63 sys.exit(1)
64
65
66 #colors = ['#ff0000', '#0863e9', '#00f200', '#ffa100',
67 # '#800000', '#805100', '#013075', '#007900']
68 colors = ['#ff0000', '#00ff00', '#0000ff',
69 '#dddd00', '#dd00dd', '#00dddd',
70 '#dd6622', '#dd2266', '#66dd22',
71 '#8844dd', '#44dd88', '#4488dd']
72
73 if len(sys.argv) < 5:
74 usage()
75
76 filename = sys.argv[1]
77 L1 = sys.argv[2]
78 L2 = sys.argv[3]
79 L3 = sys.argv[4]
80 if len(sys.argv) > 5:
81 legendHeight = float(sys.argv[5])
82 else:
83 legendHeight = 0.75
84
85 # Load the JSON data from the file
86 data = json.loads(file(filename).read())
87 conf = data['conf']
88 stats = data['stats']
89
90 # Sanity check data hierarchy
91 if len(conf['order_l1']) != len(stats.keys()):
92 error("conf.order_l1 does not match stats level 1")
93 for l1 in stats.keys():
94 if len(conf['order_l2']) != len(stats[l1].keys()):
95 error("conf.order_l2 does not match stats level 2 for %s" % l1)
96 if conf['order_l1'].count(l1) < 1:
97 error("%s not found in conf.order_l1" % l1)
98 for l2 in stats[l1].keys():
99 if len(conf['order_l3']) != len(stats[l1][l2].keys()):
100 error("conf.order_l3 does not match stats level 3")
101 if conf['order_l2'].count(l2) < 1:
102 error("%s not found in conf.order_l2" % l2)
103 for l3 in stats[l1][l2].keys():
104 if conf['order_l3'].count(l3) < 1:
105 error("%s not found in conf.order_l3" % l3)
106
107 #
108 # Generate the data based on the level specifications
109 #
110 bar_labels = None
111 group_labels = None
112 bar_vals = []
113 bar_sdvs = []
114 if L3.startswith("select="):
115 select_label = l3 = L3.split("=")[1]
116 bar_labels = conf['order_l1']
117 group_labels = conf['order_l2']
118 bar_vals = [[0]*len(group_labels) for i in bar_labels]
119 bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
120 for b in range(len(bar_labels)):
121 l1 = bar_labels[b]
122 for g in range(len(group_labels)):
123 l2 = group_labels[g]
124 bar_vals[b][g] = np.mean(stats[l1][l2][l3])
125 bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
126 elif L2.startswith("select="):
127 select_label = l2 = L2.split("=")[1]
128 bar_labels = conf['order_l1']
129 group_labels = conf['order_l3']
130 bar_vals = [[0]*len(group_labels) for i in bar_labels]
131 bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
132 for b in range(len(bar_labels)):
133 l1 = bar_labels[b]
134 for g in range(len(group_labels)):
135 l3 = group_labels[g]
136 bar_vals[b][g] = np.mean(stats[l1][l2][l3])
137 bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
138 elif L1.startswith("select="):
139 select_label = l1 = L1.split("=")[1]
140 bar_labels = conf['order_l2']
141 group_labels = conf['order_l3']
142 bar_vals = [[0]*len(group_labels) for i in bar_labels]
143 bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
144 for b in range(len(bar_labels)):
145 l2 = bar_labels[b]
146 for g in range(len(group_labels)):
147 l3 = group_labels[g]
148 bar_vals[b][g] = np.mean(stats[l1][l2][l3])
149 bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
150 else:
151 usage()
152
153 # If group is before bar then flip (zip) the data
154 if [L1, L2, L3].index("group") < [L1, L2, L3].index("bar"):
155 bar_labels, group_labels = group_labels, bar_labels
156 bar_vals = zip(*bar_vals)
157 bar_sdvs = zip(*bar_sdvs)
158
159 print "bar_vals:", bar_vals
160
161 #
162 # Now render the bar graph
163 #
164 ind = np.arange(len(group_labels)) # the x locations for the groups
165 width = 0.8 * (1.0/len(bar_labels)) # the width of the bars
166
167 fig = plt.figure(figsize=(10,6), dpi=80)
168 plot = fig.add_subplot(1, 1, 1)
169
170 rects = []
171 for i in range(len(bar_vals)):
172 rects.append(plot.bar(ind+width*i, bar_vals[i], width, color=colors[i],
173 yerr=bar_sdvs[i], align='center'))
174
175 # add some
176 plot.set_ylabel('Milliseconds (less is better)')
177 plot.set_title("Javascript array test: %s" % select_label)
178 plot.set_xticks(ind+width)
179 plot.set_xticklabels( group_labels )
180
181 fontP = FontProperties()
182 fontP.set_size('small')
183 plot.legend( [r[0] for r in rects], bar_labels, prop=fontP,
184 loc = 'center right', bbox_to_anchor = (1.0, legendHeight))
185
186 def autolabel(rects):
187 # attach some text labels
188 for rect in rects:
189 height = rect.get_height()
190 if np.isnan(height):
191 height = 0.0
192 plot.text(rect.get_x()+rect.get_width()/2., height+20, '%d'%int(height),
193 ha='center', va='bottom', size='7')
194
195 for rect in rects:
196 autolabel(rect)
197
198 # Adjust axis sizes
199 axis = list(plot.axis())
200 axis[0] = -width # Make sure left side has enough for bar
201 #axis[1] = axis[1] * 1.20 # Add 20% to the right to make sure it fits
202 axis[2] = 0 # Make y-axis start at 0
203 axis[3] = axis[3] * 1.10 # Add 10% to the top
204 plot.axis(axis)
205
206 plt.show()