diff options
Diffstat (limited to 'plot_exps.py')
| -rwxr-xr-x | plot_exps.py | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/plot_exps.py b/plot_exps.py index 2d6f06b..d49e69d 100755 --- a/plot_exps.py +++ b/plot_exps.py | |||
| @@ -1,7 +1,17 @@ | |||
| 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
| 2 | from __future__ import print_function | 2 | from __future__ import print_function |
| 3 | 3 | ||
| 4 | # Without this trickery, matplotlib uses the current X windows session | ||
| 5 | # to create graphs. Problem 1 with this: requires user has an X windows, | ||
| 6 | # through ssh -X or otherws. Problem 2: it kills the performance on the | ||
| 7 | # computer running the X session, even if that computer isn't the one | ||
| 8 | # running plot_exps.py! | ||
| 9 | import matplotlib | ||
| 10 | matplotlib.use('Agg') | ||
| 4 | import matplotlib.pyplot as plot | 11 | import matplotlib.pyplot as plot |
| 12 | |||
| 13 | import common as com | ||
| 14 | import multiprocessing | ||
| 5 | import os | 15 | import os |
| 6 | import shutil as sh | 16 | import shutil as sh |
| 7 | import sys | 17 | import sys |
| @@ -9,11 +19,11 @@ import traceback | |||
| 9 | 19 | ||
| 10 | from collections import namedtuple | 20 | from collections import namedtuple |
| 11 | from config.config import DEFAULTS | 21 | from config.config import DEFAULTS |
| 12 | from multiprocessing import Pool, cpu_count | 22 | |
| 13 | from optparse import OptionParser | 23 | from optparse import OptionParser |
| 14 | from parse.col_map import ColMap,ColMapBuilder | 24 | from parse.col_map import ColMap,ColMapBuilder |
| 15 | from parse.dir_map import DirMap | 25 | from parse.dir_map import DirMap |
| 16 | from plot.style import StyleMap | 26 | from plot.style import make_styler |
| 17 | 27 | ||
| 18 | def parse_args(): | 28 | def parse_args(): |
| 19 | parser = OptionParser("usage: %prog [options] [csv_dir]...") | 29 | parser = OptionParser("usage: %prog [options] [csv_dir]...") |
| @@ -23,7 +33,8 @@ def parse_args(): | |||
| 23 | default=DEFAULTS['out-plot']) | 33 | default=DEFAULTS['out-plot']) |
| 24 | parser.add_option('-f', '--force', action='store_true', default=False, | 34 | parser.add_option('-f', '--force', action='store_true', default=False, |
| 25 | dest='force', help='overwrite existing data') | 35 | dest='force', help='overwrite existing data') |
| 26 | parser.add_option('-p', '--processors', default=max(cpu_count() - 1, 1), | 36 | parser.add_option('-p', '--processors', |
| 37 | default=max(multiprocessing.cpu_count() - 1, 1), | ||
| 27 | type='int', dest='processors', | 38 | type='int', dest='processors', |
| 28 | help='number of threads for processing') | 39 | help='number of threads for processing') |
| 29 | 40 | ||
| @@ -53,8 +64,7 @@ def plot_by_variable(details): | |||
| 53 | builder = ColMapBuilder() | 64 | builder = ColMapBuilder() |
| 54 | config_nodes = [] | 65 | config_nodes = [] |
| 55 | 66 | ||
| 56 | # Generate mapping of (column)=>(line property to vary) for consistently | 67 | # Decode file names into configuration dicts |
| 57 | # formatted plots | ||
| 58 | for line_path, line_node in details.node.children.iteritems(): | 68 | for line_path, line_node in details.node.children.iteritems(): |
| 59 | encoded = line_path[:line_path.index(".csv")] | 69 | encoded = line_path[:line_path.index(".csv")] |
| 60 | 70 | ||
| @@ -68,14 +78,13 @@ def plot_by_variable(details): | |||
| 68 | config_nodes += [(line_config, line_node)] | 78 | config_nodes += [(line_config, line_node)] |
| 69 | 79 | ||
| 70 | col_map = builder.build() | 80 | col_map = builder.build() |
| 71 | style_map = StyleMap(col_map.columns(), col_map.get_values()) | 81 | style_map = make_styler(col_map) |
| 72 | 82 | ||
| 73 | figure = plot.figure() | 83 | figure = plot.figure() |
| 74 | axes = figure.add_subplot(111) | 84 | axes = figure.add_subplot(111) |
| 75 | 85 | ||
| 76 | # Create a line for each file node and its configuration | 86 | # Create a line for each file node and its configuration |
| 77 | for line_config, line_node in config_nodes: | 87 | for line_config, line_node in config_nodes: |
| 78 | # Create line style to match this configuration | ||
| 79 | style = style_map.get_style(line_config) | 88 | style = style_map.get_style(line_config) |
| 80 | values = sorted(line_node.values, key=lambda tup: tup[0]) | 89 | values = sorted(line_node.values, key=lambda tup: tup[0]) |
| 81 | xvalues, yvalues = zip(*values) | 90 | xvalues, yvalues = zip(*values) |
| @@ -85,14 +94,19 @@ def plot_by_variable(details): | |||
| 85 | axes.set_title(details.title) | 94 | axes.set_title(details.title) |
| 86 | 95 | ||
| 87 | lines, labels = zip(*style_map.get_key()) | 96 | lines, labels = zip(*style_map.get_key()) |
| 88 | axes.legend(tuple(lines), tuple(labels), prop={'size':10}, loc=2) | 97 | axes.legend(tuple(lines), tuple(labels), prop={'size':10}, |
| 98 | # This code places the legend slightly to the right of the plot | ||
| 99 | bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0) | ||
| 89 | 100 | ||
| 90 | axes.set_ylabel(details.value) | 101 | axes.set_ylabel(details.value) |
| 91 | axes.set_xlabel(details.variable) | 102 | axes.set_xlabel(details.variable) |
| 92 | axes.set_xlim(0, axes.get_xlim()[1]) | 103 | axes.set_xlim(0, axes.get_xlim()[1]) |
| 93 | axes.set_ylim(0, axes.get_ylim()[1]) | 104 | axes.set_ylim(0, axes.get_ylim()[1]) |
| 94 | 105 | ||
| 95 | plot.savefig(details.out, format=OUT_FORMAT) | 106 | plot.savefig(details.out, format=OUT_FORMAT, |
| 107 | # Using 'tight' causes savefig to rescale the image for non-plot | ||
| 108 | # artists, which in our case is just the legend | ||
| 109 | bbox_inches='tight') | ||
| 96 | 110 | ||
| 97 | return True | 111 | return True |
| 98 | 112 | ||
| @@ -125,8 +139,12 @@ def plot_dir(data_dir, out_dir, max_procs, force): | |||
| 125 | if not plot_details: | 139 | if not plot_details: |
| 126 | return | 140 | return |
| 127 | 141 | ||
| 128 | procs = min(len(plot_details), max_procs) | 142 | procs = min(len(plot_details), max_procs) |
| 129 | pool = Pool(processes=procs) | 143 | logged = multiprocessing.Manager().list() |
| 144 | |||
| 145 | pool = multiprocessing.Pool(processes=procs, | ||
| 146 | initializer=com.set_logged_list, initargs=(logged,)) | ||
| 147 | |||
| 130 | enum = pool.imap_unordered(plot_wrapper, plot_details) | 148 | enum = pool.imap_unordered(plot_wrapper, plot_details) |
| 131 | 149 | ||
| 132 | try: | 150 | try: |
