示例#1
0
def plot_by_variable(details):
    '''Plot each .csv files under @plot_node as a line on a shared plot.'''

    builder = ColMapBuilder()
    config_nodes = []

    # Decode file names into configuration dicts
    for line_path, line_node in details.node.children.iteritems():
        encoded = line_path[:line_path.index(".csv")]

        try:
            line_config = ColMap.decode(encoded)
        except:
            line_config = {'name': encoded}

        for k, v in line_config.iteritems():
            builder.try_add(k, v)
        config_nodes += [(line_config, line_node)]

    col_map   = builder.build()
    style_map = make_styler(col_map)

    figure = plot.figure()
    axes   = figure.add_subplot(111)

    # Create a line for each file node and its configuration
    for line_config, line_node in config_nodes:
        style  = style_map.get_style(line_config)
        values = sorted(line_node.values, key=lambda tup: tup[0])
        xvalues, yvalues = zip(*values)

        plot.plot(xvalues, yvalues, style.fmt())

    axes.set_title(details.title)

    lines, labels = zip(*style_map.get_key())
    axes.legend(tuple(lines), tuple(labels), prop={'size':10},
	    # This code places the legend slightly to the right of the plot
        bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0)

    axes.set_ylabel(details.value)
    axes.set_xlabel(details.variable)
    axes.set_xlim(0, axes.get_xlim()[1])
    axes.set_ylim(0, axes.get_ylim()[1])

    plot.savefig(details.out, format=OUT_FORMAT,
    	# Using 'tight' causes savefig to rescale the image for non-plot
	    # artists, which in our case is just the legend
        bbox_inches='tight')

    return True
def main():
    opts, args = parse_args()
    exp_dirs = get_dirs(args)

    # Load experiment parameters into a ColMap
    builder = ColMapBuilder()
    exps = load_exps(exp_dirs, builder, opts.force)

    # Don't track changes in ignored parameters
    if opts.ignore:
        for param in opts.ignore.split(","):
            builder.try_remove(param)

    # Always average multiple trials
    builder.try_remove(PARAMS['trial'])
    # Only need this for feather-trace parsing
    builder.try_remove(PARAMS['cycles'])

    col_map = builder.build()
    table = TupleTable(col_map)

    fill_table(table, exps, opts)

    if not table:
        sys.stderr.write("Found no data to parse!")
        sys.exit(1)

    write_output(table, opts)
示例#3
0
def plot_by_variable(details):
    '''Plot each .csv files under @plot_node as a line on a shared plot.'''

    builder = ColMapBuilder()
    config_nodes = []

    # Generate mapping of (column)=>(line property to vary) for consistently
    # formatted plots
    for line_path, line_node in details.node.children.iteritems():
        encoded = line_path[:line_path.index(".csv")]

        try:
            line_config = ColMap.decode(encoded)
        except:
            line_config = {'name': encoded}

        for k, v in line_config.iteritems():
            builder.try_add(k, v)
        config_nodes += [(line_config, line_node)]

    col_map   = builder.build()
    style_map = StyleMap(col_map.columns(), col_map.get_values())

    figure = plot.figure()
    axes = figure.add_subplot(111)

    # Create a line for each file node and its configuration
    for line_config, line_node in config_nodes:
        # Create line style to match this configuration
        style  = style_map.get_style(line_config)
        values = sorted(line_node.values, key=lambda tup: tup[0])
        xvalues, yvalues = zip(*values)

        plot.plot(xvalues, yvalues, style.fmt())

    axes.set_title(details.title)

    lines, labels = zip(*style_map.get_key())
    axes.legend(tuple(lines), tuple(labels), prop={'size':10})

    axes.set_ylabel(details.value)
    axes.set_xlabel(details.variable)
    axes.set_xlim(0, axes.get_xlim()[1] + 1)
    axes.set_ylim(0, axes.get_ylim()[1] + 1)

    plot.savefig(details.out, format=OUT_FORMAT)

    return True
    def create_exps(self, out_dir, force, trials):
        '''Create experiments for all possible combinations of params in
        @out_dir. Overwrite existing files if @force is True.'''
        builder = ColMapBuilder()

        # Track changing values so only relevant parameters are included
        # in directory names
        for dp in DesignPointGenerator(self.params):
            for k, v in dp.iteritems():
                builder.try_add(k, v)
        col_map = builder.build()

        for dp in DesignPointGenerator(self.params):
            for trial in xrange(trials):
                # Create directory name from relevant parameters
                dir_leaf  = "sched=%s_%s" % (self.scheduler, col_map.encode(dp))
                dir_leaf  = dir_leaf.strip('_') # If there are none
                dir_leaf += ("_trial=%s" % trial) if trials > 1 else ""

                dir_path  = "%s/%s" % (out_dir, dir_leaf.strip('_'))

                if os.path.exists(dir_path):
                    if force:
                        sh.rmtree(dir_path)
                    else:
                        print("Skipping existing experiment: '%s'" % dir_path)
                        continue

                os.mkdir(dir_path)

                if trials > 1:
                    dp[PARAMS['trial']] = trial
                self.out_dir = dir_path

                self._create_exp(dict(dp))

                del(self.out_dir)
                if PARAMS['trial'] in dp:
                    del dp[PARAMS['trial']]
def write_collapsed_csvs(table, opts):
    sys.stderr.write("Collapse option specified. "
                     "Only one numeric column at a time will be plotted.\n"
                     "The values of others will be averaged. "
                     "This is dangerous and can hide important trends!\n")

    original_map = table.get_col_map()

    builder = ColMapBuilder()
    numeric_cols = []

    # Add only nonnumeric fields to builder
    for column in original_map.columns():
        numeric = True
        for v in original_map.get_values()[column]:
            try:
                float(v)
            except ValueError:
                numeric = False
                builder.try_add(column, v)
        if numeric:
            numeric_cols += [column]

    for num_column in numeric_cols:
        # Only going to consider a single number column at a time
        for num_value in original_map.get_values()[column]:
            builder.try_add(num_column, num_value)

        next_map = builder.build()
        next_table = TupleTable(next_map)

        # Re-sort data into new table using this new key
        for mapped_key, points in table:
            kv = original_map.get_kv(mapped_key)
            next_table[kv] += points

        write_csvs(next_table, opts.out)

        builder.try_remove(num_column)
示例#6
0
def main():
    opts, args = parse_args()

    args = args or [os.getcwd()]

    # Load exp parameters into a ColMap
    builder = ColMapBuilder()
    exps = load_exps(args, builder, opts.force)

    # Don't track changes in ignored parameters
    if opts.ignore:
        for param in opts.ignore.split(","):
            builder.try_remove(param)
        # Always average multiple trials
        builder.try_remove(conf.PARAMS['trial'])

    col_map = builder.build()
    result_table = TupleTable(col_map)

    sys.stderr.write("Parsing data...\n")

    procs = min(len(exps), max(cpu_count()/2, 1))
    pool = Pool(processes=procs)
    pool_args = zip(exps, [opts.force]*len(exps))
    enum = pool.imap_unordered(parse_exp, pool_args, 1)

    try:
        for i, (exp, result) in enumerate(enum):
            if opts.verbose:
                print(result)
            else:
                sys.stderr.write('\r {0:.2%}'.format(float(i)/len(exps)))
                result_table[exp.params] += [result]
        pool.close()
    except:
        pool.terminate()
        traceback.print_exc()
        raise Exception("Failed parsing!")
    finally:
        pool.join()

    sys.stderr.write('\n')

    if opts.force and os.path.exists(opts.out):
        sh.rmtree(opts.out)

    reduced_table = result_table.reduce()

    sys.stderr.write("Writing result...\n")
    if opts.write_map:
        # Write summarized results into map
        reduced_table.write_map(opts.out)
    else:
        # Write out csv directories for all variable params
        dir_map = reduced_table.to_dir_map()

        # No csvs to write, assume user meant to print out data
        if dir_map.is_empty():
            if not opts.verbose:
                sys.stderr.write("Too little data to make csv files.\n")
                for key, exp in result_table:
                    for e in exp:
                        print(e)
        else:
            dir_map.write(opts.out)