figure module
Figure creation subpackage.
This subpackage is in beta.
Use this subpackage to create publication quality figures
with matplotlib from fits generated with scipy_data_fitting
.
This subpackage works independently from scipy_data_fitting
:
it only assumes json fit files formatted according to
scipy_data_fitting.Fit.to_json
with meta=fit.metadata
.
Use Fit
to load fits saved as json files into a Fit
object.
Create a matplotlib.figure
and manage subplots with Plot
.
""" **Figure creation subpackage.** _This subpackage is in beta._ Use this subpackage to create publication quality figures with [matplotlib][1] from fits generated with [`scipy_data_fitting`][2]. This subpackage works independently from [`scipy_data_fitting`][2]: it only assumes json fit files formatted according to [`scipy_data_fitting.Fit.to_json`][3] with [`meta=fit.metadata`][4]. Use `figure.Fit` to load fits saved as json files into a `figure.Fit` object. Create a [`matplotlib.figure`][5] and manage subplots with `figure.Plot`. [1]: http://matplotlib.org/ [2]: https://pythonhosted.org/scipy-data_fitting/ [3]: https://pythonhosted.org/scipy-data_fitting/#scipy_data_fitting.Fit.to_json [4]: https://pythonhosted.org/scipy-data_fitting/#scipy_data_fitting.Fit.metadata [5]: http://matplotlib.org/api/figure_api.html """ from .fit import Fit from .plot import Plot __all__ = ['Fit', 'Plot']
Classes
class Fit
Loads a fit from a json file into a Fit
object.
class Fit: """ Loads a fit from a json file into a `figure.Fit` object. """ def __init__(self, path=None): self.path = path """ Path to the json file containing fit to load. """ @property def path(self): return self._path @path.setter def path(self, value): self._path = value @property def data(self): """ Data points as a [`numpy.ndarray`][1] in the form #!python [ [ x1, x2, x3, ... ], [ y1, y2, y3, ...] ] [1]: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html """ if not hasattr(self, '_data'): self._load() return self._data @data.setter def data(self, value): self._data = value @property def fit(self): """ Fit points as a [`numpy.ndarray`][1] in the form #!python [ [ x1, x2, x3, ... ], [ y1, y2, y3, ...] ] [1]: http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html """ if not hasattr(self, '_fit'): self._load() return self._fit @fit.setter def fit(self, value): self._fit = value @property def meta(self): """ A dictionary of metadata related to the fit. """ if not hasattr(self, '_meta'): self._load() return self._meta @meta.setter def meta(self, value): self._meta = value @property def maps(self): """ A dictionary of dictionaries. Each dictionary defines a map which is used to extend the metadata. The precise way maps interact with the metadata is defined by `figure.fit._extend_meta`. That method should be redefined or extended to suit specific use cases. """ if not hasattr(self, '_maps'): maps = {} maps['tex_symbol'] = {} maps['siunitx'] = {} maps['value_transforms'] = { '__default__': lambda x: round(x, 2), } self._maps = maps return self._maps @maps.setter def maps(self, value): self._maps = value def _load(self): if not self.path: raise RuntimeError('Must specify path to load fit from file.') raw = json.load(open(self.path)) self.data = numpy.array(raw['data']).T self.fit = numpy.array(raw['fit']).T if 'meta' in raw: self.meta = raw['meta'] else: self.meta = {} for key in self.meta: self._extend_meta(self.meta[key]) def _extend_meta(self, meta): if isinstance(meta, str): return None if isinstance(meta, dict): meta = [meta] for item in meta: if 'name' in item: key = item['name'] if 'symbol' in item: key = item['symbol'] if 'value' in item: item['disply_value'] = str(self._value_transform(key)(item['value'])) item['tex_symbol'] = self._get_tex_symbol(key) if 'units' in item: item['siunitx'] = self._get_siunitx(item['units']) else: item['siunitx'] = '' def _get_siunitx(self, key): table = self.maps['siunitx'] if key in table: return table[key] return '' def _get_tex_symbol(self, key): table = self.maps['tex_symbol'] if key in table: return table[key] return key def _value_transform(self, key): table = self.maps['value_transforms'] if key in table: return table[key] else: return table['__default__']
Ancestors (in MRO)
- Fit
- builtins.object
Static methods
def __init__(
self, path=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, path=None): self.path = path """ Path to the json file containing fit to load. """
Instance variables
var maps
A dictionary of dictionaries. Each dictionary defines a map which is used to extend the metadata.
The precise way maps interact with the metadata is defined by figure.fit._extend_meta
.
That method should be redefined or extended to suit specific use cases.
var meta
A dictionary of metadata related to the fit.
var path
Path to the json file containing fit to load.
class Plot
Use a Plot
object to create matplotlib plots
from Fit
objects.
Example:
>>> figure = Plot.new_figure() >>> fit = Fit(path='fit.json') >>> plot = Plot(fit=fit, plt=figure.add_subplot(111)) >>> plot.plot_data() >>> plot.plot_fit() >>> figure.savefig(figure.svg) >>> Plot.close_figure(figure)
class Plot(): """ Use a `figure.Plot` object to create matplotlib plots from `figure.Fit` objects. Example: #!python >>> figure = Plot.new_figure() >>> fit = Fit(path='fit.json') >>> plot = Plot(fit=fit, plt=figure.add_subplot(111)) >>> plot.plot_data() >>> plot.plot_fit() >>> figure.savefig(figure.svg) >>> Plot.close_figure(figure) """ def __init__(self, fit=None, plt=None): self.fit = fit """ The `figure.Fit` object to associate with this plot. """ self.plt = plt """ The matplotlib subplot associated with this plot. Assign the object returned by [`matplotlib.figure.Figure.add_subplot`][1] to this property. [1]: http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.add_subplot """ @property def fit(self): return self._fit @fit.setter def fit(self, value): self._fit = value @property def plt(self): return self._plt @plt.setter def plt(self, value): self._plt = value @property def options(self): """ Dictionary of options which affect the plot style. Must contain the keys `data` and `fit` whose values are dictionaries. Options given in `data` and `fit` are passed as keyword arguments to [`matplotlib.pyplot.plot`][1] for the corresponding plot. Default: #!python { 'data': {'marker': '.', 'linestyle': 'None'}, 'fit': {}, } [1]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot """ if not hasattr(self, '_options'): self._options = { 'data': {'marker': '.', 'linestyle': 'None'}, 'fit': {}, } return self._options @options.setter def options(self, value): self._options = value def plot_data(self): """ Add the data points to the plot. """ self.plt.plot(*self.fit.data, **self.options['data']) def plot_fit(self): """ Add the fit to the plot. """ self.plt.plot(*self.fit.fit, **self.options['fit']) def add_xlabel(self, text=None): """ Add a label to the x-axis. """ x = self.fit.meta['independent'] if not text: text = '$' + x['tex_symbol'] + r'$ $(\si{' + x['siunitx'] + r'})$' self.plt.set_xlabel(text) def add_ylabel(self, text=None): """ Add a label to the y-axis. """ y = self.fit.meta['dependent'] if not text: text = '$' + y['tex_symbol'] + r'$ $(\si{' + y['siunitx'] + r'})$' self.plt.set_ylabel(text) def add_text_table(self, rows, r0, dr, **kwargs): """ Add text to a plot in a grid fashion. `rows` is a list of lists (the rows). Each row contains the columns, each column is text to add to the plot. `r0` is a tuple `(x, y)` that positions the initial text. `dr` is a tuple `(dx, dy)` that determines the column and row spacing. Any keyword arguments will be passed to `matplotlib.pyplot.text`. Example: #!python >>> rows = [ ['a', '=', '1'], ['b', '=', '2'] ] >>> self.add_text_table(rows, (0.1, 0.9), (0.1, -0.1), horizontalalignment='left', verticalalignment='top') [1]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.text """ for m, row in enumerate(rows): for n, column in enumerate(row): self.plt.text(r0[0] + dr[0] * n, r0[1] + dr[1] * m, column, transform=self.plt.axes.transAxes, **kwargs) @staticmethod def new_figure(**kwargs): """ Returns a new [`matplotlib.figure.Figure`][1] object. Keyword arguments are passed to [`matplotlib.pyplot.figure`][2]. [1]: http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure [2]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figure """ return matplotlib.pyplot.figure(**kwargs) @staticmethod def close_figure(figure): """ Closes a [`matplotlib.figure.Figure`][1] object with [`matplotlib.pyplot.close`][2]. [1]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.close """ return matplotlib.pyplot.close(figure) @staticmethod def parameter_table(parameters): """ Create """ if not isinstance(parameters, list): parameters = [parameters] rows = [] for param in parameters: row = [] row.append('$' + param['tex_symbol'] + '$') row.append('$=$') row.append(r'$\SI{' + param['disply_value'] + '}{' + param['siunitx'] + '}$') rows.append(row) return rows
Ancestors (in MRO)
- Plot
- builtins.object
Static methods
def __init__(
self, fit=None, plt=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, fit=None, plt=None): self.fit = fit """ The `figure.Fit` object to associate with this plot. """ self.plt = plt """ The matplotlib subplot associated with this plot. Assign the object returned by [`matplotlib.figure.Figure.add_subplot`][1] to this property. [1]: http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.add_subplot """
def add_text_table(
self, rows, r0, dr, **kwargs)
Add text to a plot in a grid fashion.
rows
is a list of lists (the rows).
Each row contains the columns,
each column is text to add to the plot.
r0
is a tuple (x, y)
that positions the initial text.
dr
is a tuple (dx, dy)
that determines the column and row spacing.
Any keyword arguments will be passed to matplotlib.pyplot.text
.
Example:
>>> rows = [ ['a', '=', '1'], ['b', '=', '2'] ] >>> self.add_text_table(rows, (0.1, 0.9), (0.1, -0.1), horizontalalignment='left', verticalalignment='top')
def add_text_table(self, rows, r0, dr, **kwargs): """ Add text to a plot in a grid fashion. `rows` is a list of lists (the rows). Each row contains the columns, each column is text to add to the plot. `r0` is a tuple `(x, y)` that positions the initial text. `dr` is a tuple `(dx, dy)` that determines the column and row spacing. Any keyword arguments will be passed to `matplotlib.pyplot.text`. Example: #!python >>> rows = [ ['a', '=', '1'], ['b', '=', '2'] ] >>> self.add_text_table(rows, (0.1, 0.9), (0.1, -0.1), horizontalalignment='left', verticalalignment='top') [1]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.text """ for m, row in enumerate(rows): for n, column in enumerate(row): self.plt.text(r0[0] + dr[0] * n, r0[1] + dr[1] * m, column, transform=self.plt.axes.transAxes, **kwargs)
def add_xlabel(
self, text=None)
Add a label to the x-axis.
def add_xlabel(self, text=None): """ Add a label to the x-axis. """ x = self.fit.meta['independent'] if not text: text = '$' + x['tex_symbol'] + r'$ $(\si{' + x['siunitx'] + r'})$' self.plt.set_xlabel(text)
def add_ylabel(
self, text=None)
Add a label to the y-axis.
def add_ylabel(self, text=None): """ Add a label to the y-axis. """ y = self.fit.meta['dependent'] if not text: text = '$' + y['tex_symbol'] + r'$ $(\si{' + y['siunitx'] + r'})$' self.plt.set_ylabel(text)
def close_figure(
figure)
Closes a matplotlib.figure.Figure
object
with [matplotlib.pyplot.close
][2].
@staticmethod def close_figure(figure): """ Closes a [`matplotlib.figure.Figure`][1] object with [`matplotlib.pyplot.close`][2]. [1]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.close """ return matplotlib.pyplot.close(figure)
def new_figure(
**kwargs)
Returns a new matplotlib.figure.Figure
object.
Keyword arguments are passed to matplotlib.pyplot.figure
.
@staticmethod def new_figure(**kwargs): """ Returns a new [`matplotlib.figure.Figure`][1] object. Keyword arguments are passed to [`matplotlib.pyplot.figure`][2]. [1]: http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure [2]: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figure """ return matplotlib.pyplot.figure(**kwargs)
def parameter_table(
parameters)
Create
@staticmethod def parameter_table(parameters): """ Create """ if not isinstance(parameters, list): parameters = [parameters] rows = [] for param in parameters: row = [] row.append('$' + param['tex_symbol'] + '$') row.append('$=$') row.append(r'$\SI{' + param['disply_value'] + '}{' + param['siunitx'] + '}$') rows.append(row) return rows
def plot_data(
self)
Add the data points to the plot.
def plot_data(self): """ Add the data points to the plot. """ self.plt.plot(*self.fit.data, **self.options['data'])
def plot_fit(
self)
Add the fit to the plot.
def plot_fit(self): """ Add the fit to the plot. """ self.plt.plot(*self.fit.fit, **self.options['fit'])
Instance variables
var options
Dictionary of options which affect the plot style.
Must contain the keys data
and fit
whose values are dictionaries.
Options given in data
and fit
are passed as keyword arguments
to matplotlib.pyplot.plot
for the corresponding plot.
Default:
{ 'data': {'marker': '.', 'linestyle': 'None'}, 'fit': {}, }
var plt
The matplotlib subplot associated with this plot.
Assign the object returned by matplotlib.figure.Figure.add_subplot
to this property.