aboutsummaryrefslogtreecommitdiffstats
path: root/plot_exps.py
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-02-11 18:28:31 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-02-11 18:28:31 -0500
commitb2fa65ecfe14bb9377fbd8afa5f457a07472b6fb (patch)
tree5bb1402027e1c56eccf38682166b1850c8b89aa9 /plot_exps.py
parent7c647198fc40e72ef6ca23c2484bf49eba2079ee (diff)
First attempt at plot_exps.py.
Diffstat (limited to 'plot_exps.py')
-rwxr-xr-xplot_exps.py236
1 files changed, 129 insertions, 107 deletions
diff --git a/plot_exps.py b/plot_exps.py
index 46784bc..39529bd 100755
--- a/plot_exps.py
+++ b/plot_exps.py
@@ -2,76 +2,14 @@
2from __future__ import print_function 2from __future__ import print_function
3 3
4import os 4import os
5import re
6import plot
7import shutil as sh 5import shutil as sh
8 6import sys
9from collections import defaultdict
10from optparse import OptionParser 7from optparse import OptionParser
11from gnuplot import Plot, curve 8from parse.dir_map import DirMap
12from random import randrange 9from parse.tuple_table import ReducedTupleTable
13 10from parse.col_map import ColMap
14class StyleMaker(object): 11from collections import namedtuple,defaultdict
15 LINE_WIDTH = 1.5 12import matplotlib.pyplot as plot
16 POINT_SIZE = 0.6
17 BEST_COLORS = [
18 '#ff0000', # red
19 '#000001', # black
20 '#0000ff', # blue
21 '#be00c4', # purple
22 '#ffd700', # yellow
23 ]
24
25 def __init__(csvs):
26 self.main_key, self.col_map = __find_columns(csvs)
27 self.cur_style = 1
28
29 # Use this for least-common varying attribute
30 self.main_map = {}
31 # Everything else is a color
32 self.color_map = TupleTable(self.col_map)
33
34 def __find_columns(csvs):
35 vals = defaultdict(lambda:set)
36
37 for csv in csvs:
38 to_decode = os.path.splitext(csv_file)[0]
39 params = plot.decode(to_decode)
40 for k,v in params.iteritems:
41 vals[k].add(v)
42
43 try:
44 main_key = min([(k,v) for (k,v) in thing.iteritems() if len(v) > 1],
45 key=operator.itemgetter(1))[0]
46 except ValueError:
47 main_key = None
48
49 col_map = ColMap()
50 for k,v in vals.iterkeys():
51 if k == self.main_key: continue
52 for i in v:
53 self.col_map.try_add(k, i)
54 return (main_key, col_map)
55
56 def __rand_color():
57 return "#%s" % "".join([hex(randrange(0, 255))[2:] for i in range(3)])
58
59 def get_style(csv):
60 to_decode = os.path.splitext(csv_file)[0]
61 params = plot.decode(to_decode)
62
63 if kv not in self.color_map:
64 color = best.pop() if BEST_COLORS else __rand_color()
65 self.color_map.add_exp(params, color)
66
67 if self.main_key in params:
68 val = params[self.main_key]
69 if val not in self.main_map:
70 self.main_map[val] = self.cur_style
71 self.cur_style += 1
72 style = self.main_map[val]
73 else:
74 style = 1
75 13
76def parse_args(): 14def parse_args():
77 parser = OptionParser("usage: %prog [options] [csv_dir]...") 15 parser = OptionParser("usage: %prog [options] [csv_dir]...")
@@ -83,54 +21,138 @@ def parse_args():
83 21
84 return parser.parse_args() 22 return parser.parse_args()
85 23
86def get_label(kv):
87 label = []
88 for key, value in kv.iteritems():
89 label += ["%s=%s" % (key.capitalize(), value)]
90 return ", ".join(label)
91
92def add_line(plot, csv_file):
93 to_decode = os.path.splitext(csv_file)[0]
94 params = plot.decode(to_decode)
95
96def get_stat(path, name):
97 full = os.path.abspath(path)
98 rstr = r"(?P<STAT>[^/]+)/((max|min|var|avg)/)*(%s/?)?$" % name
99 regex = re.compile(rstr, re.I | re.M)
100 match = regex.search(full)
101 return match.group("STAT")
102
103def plot_exp(name, data_dir, out_dir):
104 p = Plot()
105 p.format = 'pdf'
106 p.output = "%s/%s.pdf" % (out_dir, name)
107 p.xlabel = name.replace("vary-", "")
108 p.ylabel = get_stat(data_dir, name)
109 p.font = 'Helvetica'
110 p.dashed_lines = True
111 p.enhanced_text = True
112 p.size = ('5.0cm', '5.0cm')
113 p.font_size = '6pt'
114 p.key = 'on bmargin center horizontal'
115
116 csvs = [f for f in os.listdir(data_dir) if re.match("*.csv", f)]
117 col_map = get_col_map(csvs)
118 24
25ExpDetails = namedtuple('ExpDetails', ['variable', 'value', 'title', 'out'])
26OUT_FORMAT = 'pdf'
27
28def get_details(path):
29 out = "_".join(path) if path else "plot"
30
31 value = path.pop() if path else None
32 variable = path.pop() if path else None
33
34 title = value.capitalize() if value else ""
35 title += " by %s" % variable if variable else ""
36 title += " (%s)" % (", ".join(path)) if path else ""
37
38 return ExpDetails(variable, value, title, out)
39
40
41
42class StyleMap(object):
43 COLORS = list('bgrcmyk')
44 LINES = ['-', ':', '--']
45 MARKERS = list('.,ov^<>1234sp*hH+xDd|_')
46 ORDER = [MARKERS, COLORS, LINES]
47 DEFAULT = ["k", "-", "k"]
48
49 def __init__(self, col_list, col_values):
50 self.prop_map = dict(zip(col_list, StyleMap.ORDER))
51
52 # Store 1 style per value
53 self.value_map = defaultdict(dict)
54 for column, styles in self.prop_map.iteritems():
55 value_styles = self.value_map[column]
56 for value in sorted(col_values[column]):
57 value_styles[value] = styles.pop(0)
58 styles += [value_styles[value]]
59
60 def get_style(self, kv):
61 style = ''
62 for k,v in kv.iteritems():
63 if k in self.value_map:
64 style += self.value_map[k][v]
65 return style
66
67 def get_key(self):
68 key = []
69 for column, properties in self.prop_map.iteritems():
70 idx = StyleMap.ORDER.index(properties)
71 prop_string = StyleMap.DEFAULT[idx] + "%s"
72 for value, prop in self.value_map[column].iteritems():
73 style = plot.plot([],[], prop_string%prop)[0]
74 key += [(style, "%s:%s" % (column, value))]
75 return sorted(key, key=lambda x:x[1])
76
77def plot_by_variable(dir_map, col_map, out_dir, force):
78 num_plots = 0
79 id = 0
80 for _,_ in dir_map.leafs(1):
81 num_plots += 1
82 sys.stderr.write("Plotting by variable...")
83
84 for plot_path, plot_node in dir_map.leafs(1):
85 id += 1
86 details = get_details(plot_path)
87 out_fname = "%s/%s.%s" % (out_dir, details.out, OUT_FORMAT)
88 if os.path.exists(out_fname) and not force:
89 continue
90
91 # Kinda bad...
92 first_csv = plot_node.children.keys()[0]
93 first_config = ColMap.decode(first_csv[:first_csv.index('.csv')])
94 columns = filter(lambda c: c in first_config, col_map.columns())
95
96 style_map = StyleMap(columns, col_map.get_values())
97
98 figure = plot.figure()
99 axes = figure.add_subplot(111)
100
101 for line_path, line_node in plot_node.children.iteritems():
102 encoded = line_path[:line_path.index(".csv")]
103 config = ColMap.decode(encoded)
104 style = style_map.get_style(config)
105
106 values = sorted(line_node.values, key=lambda tup: tup[0])
107 xvalues, yvalues = zip(*values)
108
109 plot.plot(xvalues, yvalues, style)
110
111 lines, labels = zip(*style_map.get_key())
112
113 axes.legend(tuple(lines), tuple(labels), prop={'size':10})
114 axes.set_ylabel(details.value)
115 axes.set_xlabel(details.variable)
116 axes.set_xlim(0, axes.get_xlim()[1] + 1)
117 axes.set_ylim(0, axes.get_ylim()[1] + 1)
118
119 axes.set_title(details.title)
120
121 plot.savefig(out_fname, format=OUT_FORMAT)
122
123 sys.stderr.write('\r {0:.2%}'.format(float(id)/num_plots))
124 sys.stderr.write('\n')
125
126def plot_exp(data_dir, out_dir, force):
127 print("Reading data...")
128 dir_map = DirMap.read(data_dir)
129 print("Sorting configs...")
130 tuple_table = ReducedTupleTable.from_dir_map(dir_map)
131 col_map = tuple_table.get_col_map()
132
133 if not os.path.exists(out_dir):
134 os.mkdir(out_dir)
135
136 print("Plotting data...")
137 plot_by_variable(dir_map, col_map, out_dir, force)
138 # plot_by_config(tuple_table, out_dir)
119 139
120def main(): 140def main():
121 opts, args = parse_args() 141 opts, args = parse_args()
122 args = args or [os.getcwd()] 142 args = args or [os.getcwd()]
123 143
124 # if opts.force and os.path.exists(opts.out_dir): 144 if opts.force and os.path.exists(opts.out_dir):
125 # sh.rmtree(opts.out_dir) 145 sh.rmtree(opts.out_dir)
126 # if not os.path.exists(opts.out_dir): 146 if not os.path.exists(opts.out_dir):
127 # os.mkdir(opts.out_dir) 147 os.mkdir(opts.out_dir)
128 148
129 for exp in args: 149 for exp in args:
130 name = os.path.split(exp)[1] 150 name = os.path.split(exp)[1]
131 out_dir = "%s/%s" % (opts.out_dir, exp) 151 if exp != os.getcwd():
132 152 out_dir = "%s/%s" % (opts.out_dir, name)
133 plot_exp(name, exp, out_dir) 153 else:
154 out_dir = os.getcwd()
155 plot_exp(exp, out_dir, opts.force)
134 156
135if __name__ == '__main__': 157if __name__ == '__main__':
136 main() 158 main()