KVM test: introduce VM exceptions
[autotest-zwu.git] / tko / plotgraph.py
blob4bf359a54cdbf51a6066570269bd5cced306d2a6
1 # Copyright Martin J. Bligh (mbligh@google.com), 2007
3 """
4 Class to draw gnuplot graphs for autotest performance analysis.
5 Not that generic - specifically designed to to draw graphs of one type,
6 but probably adaptable.
7 """
9 import subprocess, sys, os
10 from math import sqrt
11 Popen = subprocess.Popen
13 def avg_dev(values):
14 if len(values) == 0:
15 return (0,0)
16 average = float(sum(values)) / len(values)
17 sum_sq_dev = sum( [(x - average) ** 2 for x in values] )
18 std_dev = sqrt(sum_sq_dev / float(len(values)));
19 return (average, std_dev);
22 class gnuplot:
23 def __init__(self, title, xlabel, ylabel, xsort = sorted, size = "1180,900", keytitle = None):
24 self.title = title
25 self.xlabel = xlabel
26 self.ylabel = ylabel
27 self.data_titles = []
28 self.datasets = []
29 self.xsort = xsort
30 self.xvalues = set([])
31 self.size = size
32 self.keytitle = keytitle
34 def xtics(self):
35 count = 1
36 tics = []
37 for label in self.xlabels:
38 # prepend 2 blanks to work around gnuplot bug
39 # in placing X axis legend over X tic labels
40 tics.append('" %s" %d' % (label, count))
41 count += 1
42 return tics
45 def add_dataset(self, title, labeled_values):
46 """
47 Add a data line
49 title: title of the dataset
50 labeled_values: dictionary of lists
51 { label : [value1, value2, ... ] , ... }
52 """
53 if not labeled_values:
54 raise "plotgraph:add_dataset - dataset was empty! %s" %\
55 title
56 self.data_titles.append(title)
57 data_points = {}
58 for label in labeled_values:
59 point = "%s %s" % avg_dev(labeled_values[label])
60 data_points[label] = point
61 self.xvalues.add(label)
62 self.datasets.append(data_points)
65 def plot(self, cgi_header = False, output = None, test = None):
66 if cgi_header:
67 print "Content-type: image/png\n"
68 sys.stdout.flush()
69 if test:
70 g = open(test, 'w')
71 else:
72 p = Popen("/usr/bin/gnuplot", stdin = subprocess.PIPE)
73 g = p.stdin
74 g.write('set terminal png size %s\n' % self.size)
75 if self.keytitle:
76 g.write('set key title "%s"\n' % self.keytitle)
77 g.write('set key outside\n') # outside right
78 else:
79 g.write('set key below\n')
80 g.write('set title "%s"\n' % self.title)
81 g.write('set xlabel "%s"\n' % self.xlabel)
82 g.write('set ylabel "%s"\n' % self.ylabel)
83 if output:
84 g.write('set output "%s"\n' % output)
85 g.write('set style data yerrorlines\n')
86 g.write('set grid\n')
88 self.xlabels = self.xsort(list(self.xvalues))
90 g.write('set xrange [0.5:%f]\n' % (len(self.xvalues)+0.5))
91 g.write('set xtics rotate (%s)\n' % ','.join(self.xtics()))
93 plot_lines = ['"-" title "%s"' % t for t in self.data_titles]
94 g.write('plot ' + ', '.join(plot_lines) + '\n')
96 for dataset in self.datasets:
97 count = 1
98 for label in self.xlabels:
99 if label in dataset:
100 data = dataset[label]
101 g.write("%d %s\n" % (count, str(data)))
102 count += 1
103 sys.stdout.flush()
104 g.write('e\n')
106 g.close()
107 if not test:
108 sts = os.waitpid(p.pid, 0)