diff options
author | Joel Martin <jmartin@sentryds.com> | 2011-08-25 12:24:52 -0500 |
---|---|---|
committer | Joel Martin <jmartin@sentryds.com> | 2011-08-25 12:24:52 -0500 |
commit | 65edee7696dc40dbc3e1a068c7767257be1f6bd1 (patch) | |
tree | b7e54cd8a149b4ad3ceaeacc41987e51aeee2d5f /utils/json2graph.py | |
parent | 1d7af907209f3f1e3a7bad40ff9413b358d2c206 (diff) | |
download | novnc-html5-test.tar.gz |
Fix menu. Add web-socket-js and websockify.html5-test
Diffstat (limited to 'utils/json2graph.py')
-rwxr-xr-x | utils/json2graph.py | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/utils/json2graph.py b/utils/json2graph.py new file mode 100755 index 0000000..0f6a7ad --- /dev/null +++ b/utils/json2graph.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python + +''' +Use matplotlib to generate performance charts +Copyright 2011 Joel Martin +Licensed under GPL version 3 (see docs/LICENSE.GPL-3) +''' + +# a bar plot with errorbars +import sys, json, pprint +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.font_manager import FontProperties + +def usage(): + print "%s json_file level1 level2 level3 [legend_height]\n\n" % sys.argv[0] + print "Description:\n" + print "level1, level2, and level3 are one each of the following:\n"; + print " select=ITEM - select only ITEM at this level"; + print " bar - each item on this level becomes a graph bar"; + print " group - items on this level become groups of bars"; + print "\n"; + print "json_file is a file containing json data in the following format:\n" + print ' {'; + print ' "conf": {'; + print ' "order_l1": ['; + print ' "level1_label1",'; + print ' "level1_label2",'; + print ' ...'; + print ' ],'; + print ' "order_l2": ['; + print ' "level2_label1",'; + print ' "level2_label2",'; + print ' ...'; + print ' ],'; + print ' "order_l3": ['; + print ' "level3_label1",'; + print ' "level3_label2",'; + print ' ...'; + print ' ]'; + print ' },'; + print ' "stats": {'; + print ' "level1_label1": {'; + print ' "level2_label1": {'; + print ' "level3_label1": [val1, val2, val3],'; + print ' "level3_label2": [val1, val2, val3],'; + print ' ...'; + print ' },'; + print ' "level2_label2": {'; + print ' ...'; + print ' },'; + print ' },'; + print ' "level1_label2": {'; + print ' ...'; + print ' },'; + print ' ...'; + print ' },'; + print ' }'; + sys.exit(2) + +def error(msg): + print msg + sys.exit(1) + + +#colors = ['#ff0000', '#0863e9', '#00f200', '#ffa100', +# '#800000', '#805100', '#013075', '#007900'] +colors = ['#ff0000', '#00ff00', '#0000ff', + '#dddd00', '#dd00dd', '#00dddd', + '#dd6622', '#dd2266', '#66dd22', + '#8844dd', '#44dd88', '#4488dd'] + +if len(sys.argv) < 5: + usage() + +filename = sys.argv[1] +L1 = sys.argv[2] +L2 = sys.argv[3] +L3 = sys.argv[4] +if len(sys.argv) > 5: + legendHeight = float(sys.argv[5]) +else: + legendHeight = 0.75 + +# Load the JSON data from the file +data = json.loads(file(filename).read()) +conf = data['conf'] +stats = data['stats'] + +# Sanity check data hierarchy +if len(conf['order_l1']) != len(stats.keys()): + error("conf.order_l1 does not match stats level 1") +for l1 in stats.keys(): + if len(conf['order_l2']) != len(stats[l1].keys()): + error("conf.order_l2 does not match stats level 2 for %s" % l1) + if conf['order_l1'].count(l1) < 1: + error("%s not found in conf.order_l1" % l1) + for l2 in stats[l1].keys(): + if len(conf['order_l3']) != len(stats[l1][l2].keys()): + error("conf.order_l3 does not match stats level 3") + if conf['order_l2'].count(l2) < 1: + error("%s not found in conf.order_l2" % l2) + for l3 in stats[l1][l2].keys(): + if conf['order_l3'].count(l3) < 1: + error("%s not found in conf.order_l3" % l3) + +# +# Generate the data based on the level specifications +# +bar_labels = None +group_labels = None +bar_vals = [] +bar_sdvs = [] +if L3.startswith("select="): + select_label = l3 = L3.split("=")[1] + bar_labels = conf['order_l1'] + group_labels = conf['order_l2'] + bar_vals = [[0]*len(group_labels) for i in bar_labels] + bar_sdvs = [[0]*len(group_labels) for i in bar_labels] + for b in range(len(bar_labels)): + l1 = bar_labels[b] + for g in range(len(group_labels)): + l2 = group_labels[g] + bar_vals[b][g] = np.mean(stats[l1][l2][l3]) + bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) +elif L2.startswith("select="): + select_label = l2 = L2.split("=")[1] + bar_labels = conf['order_l1'] + group_labels = conf['order_l3'] + bar_vals = [[0]*len(group_labels) for i in bar_labels] + bar_sdvs = [[0]*len(group_labels) for i in bar_labels] + for b in range(len(bar_labels)): + l1 = bar_labels[b] + for g in range(len(group_labels)): + l3 = group_labels[g] + bar_vals[b][g] = np.mean(stats[l1][l2][l3]) + bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) +elif L1.startswith("select="): + select_label = l1 = L1.split("=")[1] + bar_labels = conf['order_l2'] + group_labels = conf['order_l3'] + bar_vals = [[0]*len(group_labels) for i in bar_labels] + bar_sdvs = [[0]*len(group_labels) for i in bar_labels] + for b in range(len(bar_labels)): + l2 = bar_labels[b] + for g in range(len(group_labels)): + l3 = group_labels[g] + bar_vals[b][g] = np.mean(stats[l1][l2][l3]) + bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) +else: + usage() + +# If group is before bar then flip (zip) the data +if [L1, L2, L3].index("group") < [L1, L2, L3].index("bar"): + bar_labels, group_labels = group_labels, bar_labels + bar_vals = zip(*bar_vals) + bar_sdvs = zip(*bar_sdvs) + +print "bar_vals:", bar_vals + +# +# Now render the bar graph +# +ind = np.arange(len(group_labels)) # the x locations for the groups +width = 0.8 * (1.0/len(bar_labels)) # the width of the bars + +fig = plt.figure(figsize=(10,6), dpi=80) +plot = fig.add_subplot(1, 1, 1) + +rects = [] +for i in range(len(bar_vals)): + rects.append(plot.bar(ind+width*i, bar_vals[i], width, color=colors[i], + yerr=bar_sdvs[i], align='center')) + +# add some +plot.set_ylabel('Milliseconds (less is better)') +plot.set_title("Javascript array test: %s" % select_label) +plot.set_xticks(ind+width) +plot.set_xticklabels( group_labels ) + +fontP = FontProperties() +fontP.set_size('small') +plot.legend( [r[0] for r in rects], bar_labels, prop=fontP, + loc = 'center right', bbox_to_anchor = (1.0, legendHeight)) + +def autolabel(rects): + # attach some text labels + for rect in rects: + height = rect.get_height() + if np.isnan(height): + height = 0.0 + plot.text(rect.get_x()+rect.get_width()/2., height+20, '%d'%int(height), + ha='center', va='bottom', size='7') + +for rect in rects: + autolabel(rect) + +# Adjust axis sizes +axis = list(plot.axis()) +axis[0] = -width # Make sure left side has enough for bar +#axis[1] = axis[1] * 1.20 # Add 20% to the right to make sure it fits +axis[2] = 0 # Make y-axis start at 0 +axis[3] = axis[3] * 1.10 # Add 10% to the top +plot.axis(axis) + +plt.show() |