'''
This module contains the Results superclass and all corresponding subclasses.
'''
from __future__ import(
division,
print_function,
)
__docformat__ = 'restructuredtext en'
__all__ = ['RpoIsotopes']
import matplotlib.pyplot as plt
import numpy as np
import warnings
from collections import Sequence
#import exceptions
from .exceptions import(
ArrayError,
LengthError,
StringError,
)
#import helper functions
from .core_functions import(
assert_len,
)
from .plotting_helper import(
_plot_dicts_iso,
_rem_dup_leg,
)
from .summary_helper import(
_calc_ri_info,
)
from .results_helper import(
_calc_E_frac,
_rpo_blk_corr,
_rpo_extract_iso,
_rpo_kie_corr,
_rpo_mass_bal_corr,
)
class Results(object):
'''
Class to store resulting data (e.g. Rpo isotopes, pyGC composition, etc.).
Intended for subclassing. Do not call directly.
'''
def __init__(self):
'''
Initialize the superclass
'''
raise NotImplementedError
#define classmethod for creating instance and populating measured values
# directly from a .csv file
@classmethod
def from_csv(cls, file):
raise NotImplementedError
#define plotting method
def plot(self, ax = None, labs = None, md = None, rd = None):
'''
Method for plotting ``rp.TimeData`` instance data.
Parameters
----------
axis : matplotlib.axis or None
Axis handle to plot on. Defaults to `None`.
labs : tuple
Tuple of axis labels, in the form (x_label, y_label).
Defaults to `None`.
md : tuple or None
Tuple of modelled (i.e. rate distributions for each fraction)
data, in the form (x_data, y_data). Defaults to `None`.
Only exists for plots of fraction-specific rate data.
rd : tuple
Tuple of real (observed) data, in the form (x_data, y_data).
Defaults to `None`. If this is a scatter plot of isotope results,
then tuple is in the form (x_data, y_data, x_std, y_std).
Returns
-------
ax : matplotlib.axis
Updated axis handle containing data.
'''
#create axis if necessary and label
if ax is None:
_, ax = plt.subplots(1, 1)
#label axes if labels exist
if labs is not None:
ax.set_xlabel(labs[0])
ax.set_ylabel(labs[1])
#add fraction-specific rate data if it exists
if md is not None:
#loop through each fraction and plot
for frac in md[1]:
ax.fill_between(
md[0],
np.zeros(len(md[0])),
frac,
facecolor = [0.3,0.3,0.3],
edgecolor = 'k',
alpha = 0.3,
label = r'$\Pi_{f}(E)$')
#set limits
ax.set_xlim([0.9*np.min(md[0]), 1.1*np.max(md[0])])
ax.set_ylim([0.9*np.min(md[1]), 1.1*np.max(md[1])])
#add real data (i.e. total rate data) if it exists
if rd is not None:
ax.plot(
rd[0],
rd[1],
linewidth = 2,
color = 'k',
label = r'$p(0,E)$')
#(re)set limits
ax.set_xlim([0.9*np.min(rd[0]), 1.1*np.max(rd[0])])
ax.set_ylim([0.9*np.min(rd[1]), 1.1*np.max(rd[1])])
else:
#plot the isotope vs. rate scatter plots
ax.errorbar(
rd[0],
rd[1],
xerr = rd[2],
yerr = rd[3],
marker = 'o',
ecolor = 'k',
markersize = 12,
mec = 'k',
mfc = 'w',
elinewidth = 1,
markeredgewidth = 1,
capsize = 0,
ls = 'none')
#set x limits
ax.set_xlim([0.9*np.min(rd[0]), 1.1*np.max(rd[0])])
#determine y spread and set limits
ymin = np.min(rd[1]) - 0.1*(np.max(rd[1]) - np.min(rd[1]))
ymax = np.max(rd[1]) + 0.1*(np.max(rd[1]) - np.min(rd[1]))
ax.set_ylim([ymin, ymax])
#remove duplicate legend entries
han_list, lab_list = _rem_dup_leg(ax)
ax.legend(
han_list,
lab_list,
loc = 'best',
frameon = False)
#make tight layout
plt.tight_layout()
return ax
[docs]class RpoIsotopes(Results):
__doc__='''
Class for inputting Ramped PyrOx isotopes, calculating p(0,E) contained in
each RPO fraction, correcting isotope values for blank contribution, mass
balance, and kinetic fractionation (d13C only), and storing resulting data
and statistics.
Parameters
----------
blk_corr : boolean
Boolean to determine if inputted isotope data have been blank
corrected, defaults to `False`.
d13C_raw : None or array-like
Array of the raw d13C values (VPDB) of each measured fraction, length
`nFrac`. Defaults to `None`.
d13C_raw_std : None or array-like
The standard deviation of `d13C_raw` with length `nFrac`. Defaults to
zeros or `None` if `d13C_raw` is `None`.
Fm_raw : None or array-like
Array of the raw Fm values of each measured fraction, length `nFrac`.
Defaults to `None`.
Fm_raw_std : None or array-like
The standard deviation of `Fm_raw` with length `nFrac`. Defaults to
zeros or `None` if `Fm_raw` is `None`.
kie_corr : boolean
Boolean to determine if inputted d13C data have been fractionation
corrected, defaults to `False`.
m_raw : None or array-like
Array of the raw masses (ugC) of each measured fraction, length
`nFrac`. Defaults to `None`.
m_raw_std : None or array-like
The standard deviation of `d13C_raw` with length `nFrac`. Defaults to
zero or `None` if `m_raw` is `None`.
mb_corr : boolean
Boolean to determine if inputted d13C data have been mass-balance
corrected, defaults to `False`.
model : rp.Daem
``rp.Daem`` instance associated with the inputted energy complex,
used for calculating the fractional E distributions and for KIE
d13C correction.
ratedata : rp.EnergyComplex
``rp.EnergyComplex`` instance containing p(0,E) distribution for the
thermogram associated with inputted isotopes. Used for calculating
the fractional E distributions and for KIE d13C correction.
t_frac : None or array-like
2d array of the initial and final times of each fraction, in seconds.
Shape [`nFrac` x 2]. Defaults to `None`.
Warnings
--------
UserWarning
If using an an isothermal model type for an RPO run.
UserWarning
If using a non-energy complex ratedata type for an RPO run.
Raises
------
ArrayError
If `t_frac` is not array-like.
ArrayError
If `nE` is not the same in the ``rp.Model`` instance and the
``rp.RateData`` instance.
Notes
-----
When inputting `t_frac`, a time of 0 (i.e. `t0`, the initial time) is
defined as the first timepoint in the ``RpoThermogram`` instance. If time
passed between the thermogram `t0` and the beginning of fraction 1
trapping (as is almost always the case), `t_frac` must be adjusted
accordingly. This is done automatically when importing from .csv (see
``RpoIsotopes.from_csv``) documenatation for info.
See Also
--------
Daem
``Model`` subclass used to generate the transform for RPO
data and translate between time- and E-space.
EnergyComplex
``RateData`` subclass for storing and analyzing RPO rate data.
RpoThermogram
``TimeData`` subclass containing the time and fraction remaining data
used for the inversion.
Examples
--------
Generating a bare-bones isotope result instance containing only arbitrary
time and Fm data for a given energy complex instance, ec, and a given
model instance, Daem::
#import modules
import rampedpyrox as rp
import numpy as np
#generate arbitrary data for 3 fractions
t_frac = [[100, 200], [200, 300], [300, 1000]]
t_frac = np.array(t_frac)
Fm_raw = [1.0, 0.5, 0.0]
#create instance
ri = rp.RpoIsotopes(
daem,
ec,
t_frac,
Fm_raw = Fm_raw)
Generating a isotope result instance using an RPO output .csv file and the
``RpoIsotopes.from_csv`` class method::
#import modules
import rampedpyrox as rp
#create path to data file
file = 'path_to_folder_containing_data/isotope_data.csv'
#create instance
ri = rp.RpoThermogram.from_csv(
file,
model,
ratedata,
blk_corr = True,
mass_err = 0.01,
DE = 0.0018)
This will automatically correct inputted isotopes for the inputted
instrument blank carbon contribution using the `blk_corr` flag and will
assumed a 1 percent uncertainty in mass measurements. Additionally, this
will fractionation-correct d13C data (if they exist) using a KIE DE of
1.8 J/mol. **NOTE:** See ``RpoIsotopes.from_csv`` documentation for
instructions on getting the .csv file in the right format.
Plotting resulting p(0,E) contained in each RPO fraction::
#import additional modules
import matplotlib.pyplot as plt
#create figure
fig, ax = plt.subplots(1,3)
#plot p(0,E) distributions
ax[0] = ri.plot(
ax = ax[0],
plt_var = 'p0E')
Plotting resulting isotope vs. E scatter plots::
#plot d13C data
ax[1] = ri.plot(
ax = ax[1],
plt_var = 'd13C',
plt_corr = True) #plotting corrected values
#plot Fm data
ax[2] = ri.plot(
ax = ax[2],
plt_var = 'Fm',
plt_corr = True) #plotting corrected values
Printing a summary of the raw and corrected isotope values::
#raw fraction information
print(ri.ri_raw_info)
#corrected fraction information
print(ri.ri_corr_info)
**Attributes**
d13C_corr : np.ndarray
Array of the d13C values (VPDB) of each measured fraction, corrected
for any of: blank, mass-balance, KIE. Length `nFrac`.
d13C_corr_std : np.ndarray
The standard deviation of the d13C values (VPDB) of each measured
fraction, corrected for any of: blank, mass-balance, KIE. Length
`nFrac`.
d13C_raw : np.ndarray
Array of the raw d13C values (VPDB) of each measured fraction,
length `nFrac`.
d13C_raw_std : np.ndarray
The standard deviation of `d13C_raw` with length `nFrac`.
E_frac : np.ndarray
Array of the mean E value (kJ) contained in each measured fraction as
calculated by the inverse model, length `nFrac`.
E_frac_std : np.ndarray
The standard deviation of E (kJ) contained in each measured fraction
as calculated by the inverse model, length `nFrac`.
Fm_corr : np.ndarray
Array of the blank-corrected Fm values of each measured fraction,
length `nFrac`.
Fm_corr_std : np.ndarray
The standard deviation of `Fm_corr` with length `nFrac`.
Fm_raw : np.ndarray
Array of the raw Fm values of each measured fraction, length `nFrac`.
Fm_raw_std : np.ndarray
The standard deviation of `Fm_raw` with length `nFrac`.
m_corr : np.ndarray
Array of the blank-corrected masses (ugC) of each measured fraction,
length `nFrac`.
m_corr_std : np.ndarray
The standard deviation of `m_corr` with length `nFrac`.
m_raw : np.ndarray
Array of the raw masses (ugC) of each measured fraction, length
`nFrac`.
m_raw_std : np.ndarray
The standard deviation of `m_raw` with length `nFrac`.
nFrac : int
The number of measured fractions.
ri_corr_info : pd.DataFrame
Dataframe containing the inputted summary info, using corrected
isotopes:
time (init. and final), \n
E (mean and std.), \n
mass (mean and std.), \n
d13C (mean and std.), \n
Fm (mean and std.) \n
ri_raw_info : pd.DataFrame
Dataframe containing the inputted summary info, using raw isotopes:
time (init. and final), \n
E (mean and std.), \n
mass (mean and std.), \n
d13C (mean and std.), \n
Fm (mean and std.) \n
t_frac : np.ndarray
2d array of the initial and final times of each fraction, in seconds.
Shape [`nFrac` x 2].
'''
def __init__(
self,
model,
ratedata,
t_frac,
d13C_raw = None,
d13C_raw_std = None,
Fm_raw = None,
Fm_raw_std = None,
m_raw = None,
m_raw_std = None,
blk_corr = False,
mb_corr = False,
kie_corr = False):
#assert all lenghts are the same and of the same length as t_frac, and
# store as attributes
if isinstance(t_frac, str):
raise ArrayError(
't_frac cannot be a string')
elif isinstance(t_frac, Sequence) or hasattr(t_frac, '__array__'):
n = len(t_frac)
self.t_frac = t_frac
self.nFrac = n
else:
raise ArrayError(
't_frac must be array-like')
#store existing data
if m_raw is not None:
self.m_raw = assert_len(m_raw, n)
#store stdev if it exists, zeros if not
if m_raw_std is not None:
self.m_raw_std = assert_len(m_raw_std, n)
else:
self.m_raw_std = assert_len(0, n)
if d13C_raw is not None:
self.d13C_raw = assert_len(d13C_raw, n)
#store stdev if it exists, zeros if not
if d13C_raw_std is not None:
self.d13C_raw_std = assert_len(d13C_raw_std, n)
else:
self.d13C_raw_std = assert_len(0, n)
if Fm_raw is not None:
self.Fm_raw = assert_len(Fm_raw, n)
#store stdev if it exists, zeros if not
if Fm_raw_std is not None:
self.Fm_raw_std = assert_len(Fm_raw_std, n)
else:
self.Fm_raw_std = assert_len(0, n)
#warn if model is not Daem
mod_type = type(model).__name__
if mod_type not in ['Daem']:
warnings.warn(
'Attempting to calculate E distributions using a model'
' instance of type %r. Consider using rp.Daem instance'
' instead' % mod_type, UserWarning)
#warn if ratedata is not EnergyComplex
rd_type = type(ratedata).__name__
if rd_type not in ['EnergyComplex']:
warnings.warn(
'Attempting to calculate E distributions using a ratedata'
' instance of type %r. Consider using rp.EnergyComplex'
' instance instead' % rd_type, UserWarning)
#raise exception if not the right shape
if model.nE != ratedata.nE:
raise ArrayError(
'Cannot combine model with nE = %r and RateData with'
' nE = %r. Check that RateData was not created using a'
' different model' % (model.nE, ratedata.nE))
#calculate E distributions for each fraction
E_frac, E_frac_std, p_frac = _calc_E_frac(self, model, ratedata)
#store results
self.E_frac = E_frac
self.E_frac_std = E_frac_std
#store protected energetic attributes
self._p_frac = p_frac
self._p = ratedata.p
self._E = ratedata.E
#store raw info summary table
self.ri_raw_info = _calc_ri_info(self, flag = 'raw')
#store bookkeeping corrected flags
self._blk_corr = blk_corr
self._mb_corr = mb_corr
self._kie_corr = kie_corr
#define classmethod for creating instance and populating measured values
# directly from a .csv file
[docs] @classmethod
def from_csv(
cls,
file,
model,
ratedata,
blk_corr = False,
blk_d13C = (-29.0, 0.1),
blk_flux = (0.375, 0.0583),
blk_Fm = (0.555, 0.042),
bulk_d13C_true = None,
DE = 0.0018,
mass_err = 0.01):
'''
Class method to directly import RPO fraction data from a .csv file and
create an ``RpoIsotopes`` class instance.
Parameters
----------
blk_corr : Boolean
Tells the method whether or not to blank-correct isotope data. If
`True`, blank-corrects according to inputted blank composition
values. If `bulk_d13C_true` is not `None`, further corrects d13C
values to ensure isotope mass balance (see Hemingway et al.,
Radiocarbon **2017** for details).
blk_d13C : tuple
Tuple of the blank d13C composition (VPDB), in the form
(mean, stdev.) to be used of ``blk_corr = True``. Defaults to the
NOSAMS RPO blank as calculated by Hemingway et al., Radiocarbon
**2017**.
blk_flux : tuple
Tuple of the blank flux (ng/s), in the form (mean, stdev.) to
be used of ``blk_corr = True``. Defaults to the NOSAMS RPO blank
as calculated by Hemingway et al., Radiocarbon **2017**.
blk_Fm : tuple
Tuple of the blank Fm value, in the form (mean, stdev.) to
be used of ``blk_corr = True``. Defaults to the NOSAMS RPO blank
as calculated by Hemingway et al., Radiocarbon **2017**.
bulk_d13C_true : None or array
True measured d13C value (VPDB) for bulk material as measured
independently (e.g. on a EA-IRMS). If not `None`, this value is
used to mass-balance-correct d13C values as described in Hemingway
et al., Radiocarbon **2017**. If not `none`, must be inputted in
the form [mean, stdev.]
DE : scalar
Value for the difference in E between 12C- and 13C-containing
atoms, in kJ. Defaults to 0.0018 (the best-fit value calculated
in Hemingway et al., Radiocarbon, **2017**).
file : str or pd.DataFrame
File containing RPO isotope data, either as a string pointing
to a .csv file or as a ``pd.DataFrame`` instance.
mass_err : float
Relative uncertainty in mass measurements, typically as a sum of
manometric uncertainty in pressure measurements and uncertainty in
vacuum line volumes. Defaults to 0.01 (i.e. 1\% relative
uncertainty).
model : rp.Model
``rp.Model`` instance containing the A matrix to use for
inversion.
ratedata : rp.RateData
``rp.Ratedata`` instance containing the reactive continuum data.
Notes
-----
For bookkeeping purposes, the first 2 rows must be fractions "-1" and
"0", where the timestamp for fraction "-1" is the first point in
the `all_data` file used to create the ``rp.RpoThermogram`` instance,
and the timestamp for fraction "0" is the t0 for the first fraction.
If mass, d13C, and Fm data exist, column names must be the following:
'ug_frac' and 'ug_frac_std' \n
'd13C' and 'd13C_std' \n
'Fm' and 'Fm_std'
See Also
--------
RpoThermogram.from_csv
Classmethod for creating ``rp.RpoThermogram`` instance directly
from a .csv file.
References
----------
[1] J.D. Hemingway et al. (2017) Assessing the blank carbon
contribution, isotope mass balance, and kinetic isotope
fractionation of the ramped pyrolysis/oxidation instrument at
NOSAMS. *Radiocarbon*, **59**, 179-193.
'''
#extract data from file
d13C, d13C_std, Fm, Fm_std, m, m_std, t_frac = _rpo_extract_iso(
file,
mass_err)
#create RpoIsotopes instance and store raw data
ri = cls(
model,
ratedata,
t_frac,
d13C_raw = d13C,
d13C_raw_std = d13C_std,
Fm_raw = Fm,
Fm_raw_std = Fm_std,
m_raw = m,
m_raw_std = m_std,
blk_corr = False,
mb_corr = False,
kie_corr = False)
#blank correct m, d13C, Fm if necessary
if blk_corr is True:
#call blank- and mass-balance correction method
ri.blank_correct(
blk_d13C = blk_d13C,
blk_flux = blk_flux,
blk_Fm = blk_Fm,
bulk_d13C_true = bulk_d13C_true)
#kinetic fractionation correct if necessary
if DE is not None:
#call kie correction method
ri.kie_correct(
model,
ratedata,
DE = DE)
return ri
[docs] def blank_correct(
self,
blk_d13C = (-29.0, 0.1),
blk_flux = (0.375, 0.0583),
blk_Fm = (0.555, 0.042),
bulk_d13C_true = None):
'''
Method to blank- and mass-balance correct raw isotope values.
Parameters
----------
blk_d13C : tuple
Tuple of the blank d13C composition (VPDB), in the form
(mean, stdev.) to be used of ``blk_corr = True``. Defaults to the
NOSAMS RPO blank as calculated by Hemingway et al., Radiocarbon
**2017**.
blk_flux : tuple
Tuple of the blank flux (ng/s), in the form (mean, stdev.) to
be used of ``blk_corr = True``. Defaults to the NOSAMS RPO blank
as calculated by Hemingway et al., Radiocarbon **2017**.
blk_Fm : tuple
Tuple of the blank Fm value, in the form (mean, stdev.) to
be used of ``blk_corr = True``. Defaults to the NOSAMS RPO blank
as calculated by Hemingway et al., Radiocarbon **2017**.
bulk_d13C_true : None or array
True measured d13C value (VPDB) for bulk material as measured
independently (e.g. on a EA-IRMS). If not `None`, this value is
used to mass-balance-correct d13C values as described in Hemingway
et al., Radiocarbon **2017**. If not `none`, must be inputted in
the form [mean, stdev.]
Warnings
--------
UserWarning
If already corrected for blank contribution
UserWarning
If already corrected for 13C mass balance
References
----------
[1] J.D. Hemingway et al. (2017) Assessing the blank carbon
contribution, isotope mass balance, and kinetic isotope
fractionation of the ramped pyrolysis/oxidation instrument at
NOSAMS. *Radiocarbon*, **59**, 179-193.
'''
#raise warnings
if self._blk_corr == True:
warnings.warn(
'd13C, Fm, and/or m has already been blank-corrected!'
' Proceeding anyway', UserWarning)
if self._mb_corr == True:
warnings.warn(
'd13C has already been mass-balance corrected!'
' Proceeding anyway', UserWarning)
#define constants
n = self.nFrac
#extract d13C from self to be corrected
if hasattr(self, 'd13C_corr'):
d13C = self.d13C_corr
d13C_std = self.d13C_corr_std
else:
d13C = self.d13C_raw
d13C_std = self.d13C_raw_std
#extract Fm from self to be corrected
if hasattr(self, 'Fm_corr'):
Fm = self.Fm_corr
Fm_std = self.Fm_corr_std
else:
Fm = self.Fm_raw
Fm_std = self.Fm_raw_std
#extract m from self to be corrected
if hasattr(self, 'm_corr'):
m = self.m_corr
m_std = self.m_corr_std
else:
m = self.m_raw
m_std = self.m_raw_std
#blank-correct values
d13C, d13C_std, Fm, Fm_std, m, m_std = _rpo_blk_corr(
d13C,
d13C_std,
Fm,
Fm_std,
m,
m_std,
self.t_frac,
blk_d13C = blk_d13C,
blk_flux = blk_flux,
blk_Fm = blk_Fm)
#set bookkeeping flag
self._blk_corr = True
#mass-balance correct d13C if necessary
if bulk_d13C_true is not None:
d13C, d13C_std = _rpo_mass_bal_corr(
d13C,
d13C_std,
m,
m_std,
bulk_d13C_true)
#set bookkeeping flag
self._mb_corr = True
#store corrected values if they exist
if m is not None:
self.m_corr = assert_len(m, n)
#store stdev if it exists, zeros if not
if m_std is not None:
self.m_corr_std = assert_len(m_std, n)
else:
self.m_corr_std = assert_len(0, n)
if d13C is not None:
self.d13C_corr = assert_len(d13C, n)
#store stdev if it exists, zeros if not
if d13C_std is not None:
self.d13C_corr_std = assert_len(d13C_std, n)
else:
self.d13C_corr_std = assert_len(0, n)
if Fm is not None:
self.Fm_corr = assert_len(Fm, n)
#store stdev if it exists, zeros if not
if Fm_std is not None:
self.Fm_corr_std = assert_len(Fm_std, n)
else:
self.Fm_corr_std = assert_len(0, n)
#generate summary table
self.ri_corr_info = _calc_ri_info(self, flag = 'corr')
[docs] def kie_correct(
self,
model,
ratedata,
DE = 0.0018):
'''
Method for further correcting d13C values to account for kinetic
isotope fractionation occurring within the instrument.
Parameters
----------
model : rp.Model
``rp.Model`` instance containing the A matrix to use for
inversion.
ratedata : rp.RateData
``rp.Ratedata`` instance containing the reactive continuum data.
DE : scalar
Value for the difference in E between 12C- and 13C-containing
atoms, in kJ. Defaults to 0.0018 (the best-fit value calculated
in Hemingway et al., Radiocarbon, **2017**).
Warnings
--------
UserWarning
If already corrected for kinetic fractionation
References
----------
[1] J.D. Hemingway et al. (2017) Assessing the blank carbon
contribution, isotope mass balance, and kinetic isotope
fractionation of the ramped pyrolysis/oxidation instrument at
NOSAMS. *Radiocarbon*, **59**, 179-193.
'''
#raise warnings
if self._kie_corr == True:
warnings.warn(
'd13C has already been corrected for kinetic fractionation!'
' Proceeding anyway', UserWarning)
#set constants
n = self.nFrac
#extract d13C from self to be corrected
if hasattr(self, 'd13C_corr'):
d13C = self.d13C_corr
d13C_std = self.d13C_corr_std
elif hasattr(self, 'd13C_raw'):
d13C = self.d13C_raw
d13C_std = self.d13C_raw_std
else:
return
#kie-correct values
d13C, d13C_std = _rpo_kie_corr(
self,
d13C,
d13C_std,
model,
ratedata,
DE = DE)
#set bookkeeping flag
self._kie_corr = True
#store results
self.d13C_corr = assert_len(d13C, n)
#store stdev if it exists, zeros if not
if d13C_std is not None:
self.d13C_corr_std = assert_len(d13C_std, n)
else:
self.d13C_corr_std = assert_len(0, n)
#store summary
self.ri_corr_info = _calc_ri_info(self, flag = 'corr')
#define plotting method
[docs] def plot(self, ax = None, plt_var = 'p0E', plt_corr = True):
'''
Method for plotting results, either p(0,E) distributions contained
within each RPO fraction or isotopes vs. mean E for each RPO fraction.
Parameters
----------
ax : None or matplotlib.axis
Axis to plot on. If `None`, automatically creates a
``matplotlip.axis`` instance to return. Defaults to `None`.
plt_var : str
Tells the method which variable to plot, available options are:
'p0E' (for fraction-specific p(0,E) distributions), 'Fm', and d13C
(isotope vs. fraction E scatter plots).
plt_corr : str
If `plt_var` is 'Fm' or 'd13C', `plt_corr` tells the method
whether to plot raw or corrected values (if corrected values
exist).
Returns
-------
ax : matplotlib.axis
Updated axis instance with plotted data.
Raises
------
ArrayError
if `plt_corr` is `True` but no corrected data exist.
StringError
If `plt_var` is not 'p0E', 'Fm', or 'd13C'.
'''
#check that plt_var is an appropriate string
if plt_var not in ['p0E','Fm','d13C']:
raise StringError(
'plt_var does not accept %r. Must be "p0E", "Fm", or "d13C"'
%plt_var)
#check that corrected data exist if called
if plt_var in ['Fm','d13C']:
att = plt_var + '_corr'
if plt_corr is True and not hasattr(self, att):
raise ArrayError(
'plt_corr is set to True but corrected values do not exist!')
#extract axis label ditionary
rpo_labs = _plot_dicts_iso('rpo_iso_labs', self)
labs = (
rpo_labs['E'][plt_var][0],
rpo_labs['E'][plt_var][1])
#determine attributes being plotted and generate dict
if plt_var in ['Fm','d13C']:
if plt_corr:
att = plt_var + '_corr'
#extract the right dict
iso_rd = _plot_dicts_iso('iso_corr', self)
rd = (
iso_rd['E'][att][0],
iso_rd['E'][att][1],
iso_rd['E'][att][2],
iso_rd['E'][att][3])
else:
att = plt_var + '_raw'
#extract the right dict
iso_rd = _plot_dicts_iso('iso_raw', self)
rd = (
iso_rd['E'][att][0],
iso_rd['E'][att][1],
iso_rd['E'][att][2],
iso_rd['E'][att][3])
#no modeled data exist
md = None
else:
#generate rd and md for p(0,E) plots
rd = (self._E, self._p)
md = (self._E, self._p_frac)
#call superclass method
ax = super(RpoIsotopes, self).plot(
ax = ax,
labs = labs,
md = md,
rd = rd)
return ax
if __name__ == '__main__':
import rampedpyrox as rp