From 86046c53cd026ec8c6f02d27d3c872d709c115f0 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 12 Jan 2012 12:18:32 -0500 Subject: [PATCH] Add bin/sawsim_plot_histogram_file.py and Histogram.plot(). This moves some of the matplotlib initialization into the more basic pysawsim.histogram module, and provides an easy way to display histogram files. --- bin/sawsim_plot_histogram_file.py | 15 ++++++++++ pysawsim/histogram.py | 19 ++++++++++++ pysawsim/parameter_scan.py | 49 +++++++++++++++++-------------- 3 files changed, 61 insertions(+), 22 deletions(-) create mode 100755 bin/sawsim_plot_histogram_file.py diff --git a/bin/sawsim_plot_histogram_file.py b/bin/sawsim_plot_histogram_file.py new file mode 100755 index 0000000..25e2f96 --- /dev/null +++ b/bin/sawsim_plot_histogram_file.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +from pysawsim.parameter_scan import HistogramMatcher + + +if __name__ == '__main__': + import sys + + for histfile in sys.argv[1:]: + with open(histfile, 'r') as f: + histograms = HistogramMatcher._read_force_histograms(f) + for params,histogram in sorted(histograms.items()): + histogram.plot( + title=params, + filename='histogram{}.png'.format(params.replace(' ','_'))) diff --git a/pysawsim/histogram.py b/pysawsim/histogram.py index acd1359..cdb0bbf 100644 --- a/pysawsim/histogram.py +++ b/pysawsim/histogram.py @@ -20,7 +20,10 @@ """Histogram generation and comparison. """ +import matplotlib +matplotlib.use('Agg') # select backend that doesn't require X Windows import numpy +import pylab from . import log @@ -29,6 +32,11 @@ _multiprocess_can_split_ = True """Allow nosetests to split tests between processes. """ +FIGURE = pylab.figure() # avoid memory problems. +"""`pylab` keeps internal references to all created figures, so share +a single instance. +""" + class Histogram (object): """A histogram with a flexible comparison method, `residual()`. @@ -243,3 +251,14 @@ class Histogram (object): """ r_method = getattr(self, self._type_to_method(type)) return r_method(other) + + def plot(self, title=None, filename=None): + FIGURE.clear() + axes = FIGURE.add_subplot(1, 1, 1) + axes.hist(x=self.bin_edges[:-1], # one fake entry for each bin + weights=self.counts, # weigh the fake entries by count + bins=self.bin_edges, + align='mid', histtype='stepfilled') + axes.set_title(title) + pylab.show() + FIGURE.savefig(filename) diff --git a/pysawsim/parameter_scan.py b/pysawsim/parameter_scan.py index 2dade8b..f986ce8 100644 --- a/pysawsim/parameter_scan.py +++ b/pysawsim/parameter_scan.py @@ -25,26 +25,22 @@ import os.path import pickle from StringIO import StringIO -import matplotlib -matplotlib.use('Agg') # select backend that doesn't require X Windows import numpy -import pylab from . import log from . import PYSAWSIM_LOG_LEVEL_MSG as _PYSAWSIM_LOG_LEVEL_MSG -from .histogram import Histogram +from .histogram import Histogram as _Histogram +from .histogram import FIGURE as _FIGURE from .sawsim_histogram import sawsim_histogram from .sawsim import SawsimRunner +# import after .histogram, which selects an appropriate backend +import pylab _multiprocess_can_split_ = True """Allow nosetests to split tests between processes. """ -FIGURE = pylab.figure() # avoid memory problems. -"""`pylab` keeps internal references to all created figures, so share -a single instance. -""" EXAMPLE_HISTOGRAM_FILE_CONTENTS = """# Velocity histograms # Other general comments... @@ -174,7 +170,8 @@ class HistogramMatcher (object): self.residual_type = residual_type self._plot = plot - def _read_force_histograms(self, stream): + @staticmethod + def _read_force_histograms(stream): """ File format: @@ -231,7 +228,7 @@ class HistogramMatcher (object): for params,block in hist_blocks.iteritems(): if params == None: continue - h = Histogram() + h = _Histogram() h.from_stream(StringIO('\n'.join(block))) histograms[params] = h return histograms @@ -298,8 +295,8 @@ class HistogramMatcher (object): # import pickle # [X,Y,C] = pickle.load(file("histogram_matcher-XYC.pkl", "rb")) # ... - FIGURE.clear() - axes = FIGURE.add_subplot(111) + _FIGURE.clear() + axes = _FIGURE.add_subplot(1, 1, 1) if logx == True: axes.set_xscale('log') if logy == True: @@ -310,18 +307,26 @@ class HistogramMatcher (object): else: # pseudocolor plot p = axes.pcolor(X, Y, C) axes.autoscale_view(tight=True) - FIGURE.colorbar(p) - FIGURE.savefig("figure.png") + _FIGURE.colorbar(p) + _FIGURE.savefig("figure.png") def _plot_residual_comparison(self, experiment_hist, theory_hist, residual, title, filename): - FIGURE.clear() - p = pylab.plot(experiment_hist.bin_edges[:-1], - experiment_hist.probabilities, 'r-', - theory_hist.bin_edges[:-1], - theory_hist.probabilities, 'b-') - pylab.title(title) - FIGURE.savefig(filename) + _FIGURE.clear() + axes = _FIGURE.add_subplot(1, 1, 1) + axes.hold(True) + axes.hist(x=experiment_hist.bin_edges[:-1], # one fake entry for each bin + weights=experiment_hist.counts, # weigh the fake entries by count + bins=experiment_hist.bin_edges, + align='mid', histtype='stepfilled', + color='r') + axes.hist(x=theory_hist.bin_edges[:-1], # one fake entry for each bin + weights=theory_hist.counts, # weigh the fake entries by count + bins=theory_hist.bin_edges, + align='mid', histtype='stepfilled', + color='b', alpha=0.5) + axes.set_title(title) + _FIGURE.savefig(filename) def parse_param_ranges_string(string): @@ -411,7 +416,7 @@ def main(argv=None): parser.add_option('-R','--residual', dest='residual', metavar='STRING', help='Residual type (from %s; default: %%default).' - % ', '.join(Histogram().types()), + % ', '.join(_Histogram().types()), default='jensen-shannon') parser.add_option('-P','--plot-residuals', dest='plot_residuals', help='Generate residual difference plots for each point in the plot range.', -- 2.26.2