Pyteomics documentation v4.7.1

pyteomics.pylab_aux

Contents

Source code for pyteomics.pylab_aux

"""
pylab_aux - auxiliary functions for plotting with pylab
=======================================================

This module serves as a collection of useful routines for data plotting with
matplotlib.

Generic plotting
----------------

  :py:func:`plot_line` - plot a line.

  :py:func:`scatter_trend` - plot a scatter plot with a regression line.

  :py:func:`plot_function_3d` - plot a 3D graph of a function of two variables.

  :py:func:`plot_function_contour` - plot a contour graph of a function of
  two variables.

Spectrum visualization
----------------------

  :py:func:`plot_spectrum` - plot a single spectrum (m/z vs intensity).

  :py:func:`annotate_spectrum` - plot and annotate peaks in MS/MS spectrum.

  :py:func:`mirror` - create a mirror plot of two spectra (using :py:mod:`spectrum_utils`).

FDR control
-----------

  :py:func:`plot_qvalue_curve` - plot the dependence of q-value on the amount of PSMs
  (similar to a ROC curve).

See also
--------

  - `Matplotlib cookbook <http://www.scipy.org/Cookbook/Matplotlib/>`_
  - `Matplotlib tutorial
    <http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html>`_

Dependencies
------------

This module requires :py:mod:`matplotlib`. Optional dependencies: :py:mod:`adjustText`, :py:mod:`spectrum_utils`.

-------------------------------------------------------------------------------

"""

#   Copyright 2012 Anton Goloborodko, Lev Levitsky
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import pylab
import numpy as np
from .auxiliary import linear_regression, PyteomicsError
from .version import VersionInfo
from . import parser, mass, mgf, proforma

try:
    import spectrum_utils
    if VersionInfo(spectrum_utils.__version__) < VersionInfo('0.4'):
        raise ImportError("Supported spectrum_utils version is 0.4.0 or newer.")
    import spectrum_utils.spectrum as sus
    import spectrum_utils.plot as sup
except ImportError:
    sus = sup = None


[docs] def plot_line(a, b, xlim=None, *args, **kwargs): """Plot a line y = a * x + b. Parameters ---------- a : float The slope of the line. b : float The intercept of the line. xlim : tuple, optional Minimal and maximal values of `x`. If not given, :py:func:`pylab.xlim` will be called. *args Passed to :py:func:`pylab.plot` after `x` and `y` values. **kwargs Passed to :py:func:`pylab.plot`. Returns ------- out : matplotlib.lines.Line2D The line object. """ if xlim is None: xlim = pylab.xlim() return pylab.plot([xlim[0], xlim[1]], [a * xlim[0] + b, a * xlim[1] + b], *args, **kwargs)
[docs] def scatter_trend(x, y=None, **kwargs): """Make a scatter plot with a linear regression. Parameters ---------- x : array_like of float 1-D array of floats. If `y` is omitted, `x` must be a 2-D array of shape (N, 2). y : array_like of float, optional 1-D arrays of floats. If `y` is omitted or :py:const:`None`, `x` must be a 2-D array of shape (N, 2). plot_trend : bool, optional If :py:const:`True` then plot a trendline (default). plot_sigmas : bool, optional If :py:const:`True` then plot confidence intervals of the linear fit. :py:const:`False` by default. show_legend : bool, optional If :py:const:`True`, a legend will be shown with linear fit equation, correlation coefficient, and standard deviation from the fit. Default is :py:const:`True`. title : str, optional The title. Empty by default. xlabel, ylabel : str, optional The axes labels. Empty by default. alpha_legend : float, optional Legend box transparency. 1.0 by default scatter_kwargs : dict, optional Keyword arguments for :py:func:`pylab.scatter`. Empty by default. plot_kwargs : dict, optional Keyword arguments for :py:func:`plot_line`. By default, sets `xlim` and `label`. legend_kwargs : dict, optional Keyword arguments for :py:func:`pylab.legend`. Default is :py:const:`{'loc': 'upper left'}`. sigma_kwargs : dict, optional Keyword arguments for :py:func:`pylab.plot` used for sigma lines. Default is :py:const:`{'color': 'red', 'linestyle': 'dashed'}`. sigma_values : iterable, optional Each value will be multiplied with standard error of the fit, and the line shifted by the resulting value will be plotted. Default is :py:const:`range(-3, 4)`. regression : callable, optional Function to perform linear regression. Will be given ``x`` and ``y`` as arguments. Must return a 4-tuple: (a, b, r, stderr). Default is :py:func:`pyteomics.auxiliary.linear_regression`. Returns ------- out : tuple A (scatter_plot, trend_line, sigma_lines, legend) tuple. """ regression = kwargs.get('regression', linear_regression) a, b, r, stderr = regression(x, y) pylab.title(kwargs.get('title', '')) pylab.xlabel(kwargs.get('xlabel', '')) pylab.ylabel(kwargs.get('ylabel', '')) equation = ( '$y\,=\,{:.3f}x\,{}\,{:.3f}$, ' '$R^2=\,{:.3f}$ \n$\sigma\,=\,{:.3f}$'.format( a, '-' if b < 0 else '+', abs(b), r*r, stderr)) if y is None: x = np.array(x, copy=False) y = x[:, 1] x = x[:, 0] else: x = np.array(x) y = np.array(y) sc = pylab.scatter(x, y, **kwargs.get('scatter_kwargs', {})) xlim = (x.min(), x.max()) plkw = kwargs.get('plot_kwargs', {}).copy() plkw.setdefault('xlim', xlim) plkw.setdefault('label', equation) if kwargs.get('plot_trend', True): line = plot_line(a, b, **plkw) else: line = None if kwargs.get('plot_sigmas', False): s_lines = [] sigma_kwargs = kwargs.get('sigma_kwargs', {'color': 'red', 'linestyle': 'dashed'}) for i in kwargs.get('sigma_values', range(-3, 4)): s_lines.append(plot_line(a, b + i * stderr, xlim, **sigma_kwargs)) else: s_lines = None if kwargs.get('show_legend', True): legend = pylab.legend(**kwargs.get('legend_kwargs', {'loc': 'upper left'})) legend_frame = legend.get_frame() legend_frame.set_alpha(kwargs.get('alpha_legend', 1.0)) else: legend = None return sc, line, s_lines, legend
[docs] def plot_function_3d(x, y, function, **kwargs): """Plot values of a function of two variables in 3D. More on 3D plotting in pylab: http://www.scipy.org/Cookbook/Matplotlib/mplot3D Parameters ---------- x : array_like of float The plotting range on X axis. y : array_like of float The plotting range on Y axis. function : function The function to plot. plot_type : {'surface', 'wireframe', 'scatter', 'contour', 'contourf'}, keyword only, optional The type of a plot, see `scipy cookbook <http://www.scipy.org/Cookbook/Matplotlib/mplot3D>`_ for examples. The default value is 'surface'. num_contours : int The number of contours to plot, 50 by default. xlabel : str, keyword only, optional The X axis label. Empty by default. ylabel : str, keyword only, optional The Y axis label. Empty by default. zlabel : str, keyword only, optional The Z axis label. Empty by default. title : str, keyword only, optional The title. Empty by default. **kwargs Passed to the respective plotting function. """ import mpl_toolkits.mplot3d.axes3d as pylab3d ax = pylab3d.Axes3D(pylab.gcf()) ax.set_xlabel(kwargs.pop('xlabel', '')) ax.set_ylabel(kwargs.pop('ylabel', '')) ax.set_zlabel(kwargs.pop('zlabel', '')) ax.set_title(kwargs.pop('title', '')) X, Y = np.meshgrid(x, y) Z = [] for y_value in y: Z.append([]) for x_value in x: Z[-1].append(function(x_value, y_value)) Z = np.array(Z) plot_type = kwargs.pop('plot_type', 'surface') if plot_type == 'surface': ax.plot_surface(X, Y, Z, rstride=kwargs.pop('rstride', 1), cstride=kwargs.pop('cstride', 1), cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs) elif plot_type == 'wireframe': ax.plot_wireframe(X, Y, Z, cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs) elif plot_type == 'scatter': ax.scatter3D(np.ravel(X), np.ravel(Y), np.ravel(Z), **kwargs) elif plot_type == 'contour': num_contours = kwargs.pop('num_contours', 50) ax.contour3D(X, Y, Z, num_contours, cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs) elif plot_type == 'contourf': num_contours = kwargs.pop('num_contours', 50) ax.contourf3D(X, Y, Z, num_contours, cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs) else: raise PyteomicsError('Unknown plot type: {}'.format(plot_type))
[docs] def plot_function_contour(x, y, function, **kwargs): """Make a contour plot of a function of two variables. Parameters ---------- x, y : array_like of float The positions of the nodes of a plotting grid. function : function The function to plot. filling : bool Fill contours if True (default). num_contours : int The number of contours to plot, 50 by default. xlabel, ylabel : str, optional The axes labels. Empty by default. title : str, optional The title. Empty by default. **kwargs Passed to :py:func:`pylab.contour` or :py:func:`pylab.contourf`. """ pylab.xlabel(kwargs.pop('xlabel', '')) pylab.ylabel(kwargs.pop('ylabel', '')) pylab.title(kwargs.pop('title', '')) X, Y = np.meshgrid(x, y) Z = [] for y_value in y: Z.append([]) for x_value in x: Z[-1].append(function(x_value, y_value)) Z = np.array(Z) num_contours = kwargs.pop('num_contours', 50) if kwargs.pop('filling', True): pylab.contourf(X, Y, Z, num_contours, cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs) else: pylab.contour(X, Y, Z, num_contours, cmap=kwargs.pop('cmap', pylab.cm.jet), **kwargs)
[docs] def plot_qvalue_curve(qvalues, *args, **kwargs): """ Plot a curve with q-values on the X axis and corresponding PSM number (starting with ``1``) on the Y axis. Parameters ---------- qvalues : array-like An array of q-values for sorted PSMs. xlabel : str, keyword only, optional Label for the X axis. Default is "q-value". ylabel : str, keyword only, optional Label for the Y axis. Default is "# of PSMs". title : str, keyword only, optional The title. Empty by default. *args Given to :py:func:`pylab.plot` after `x` and `y`. **kwargs Given to :py:func:`pylab.plot`. Returns ------- out : matplotlib.lines.Line2D """ pylab.xlabel(kwargs.pop('xlabel', 'q-value')) pylab.ylabel(kwargs.pop('ylabel', '# of PSMs')) pylab.title(kwargs.pop('title', '')) return pylab.plot(qvalues, 1 + np.arange(qvalues.size), *args, **kwargs)
def _default_plot_spectrum(spectrum, *args, **kwargs): ax = kwargs.pop('ax', None) or pylab.gca() if kwargs.pop('centroided', True): kwargs.setdefault('align', 'center') kwargs.setdefault('width', 0) kwargs.setdefault('linewidth', 1) kwargs.setdefault('edgecolor', 'k') ax.bar(spectrum['m/z array'], spectrum['intensity array'], *args, **kwargs) else: ax.plot(spectrum['m/z array'], spectrum['intensity array'], *args, **kwargs) return ax def _spectrum_utils_plot(spectrum, *args, **kwargs): with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): spectrum = _spectrum_utils_create_spectrum(spectrum, None, *args, **kwargs) return sup.spectrum(spectrum) def _spectrum_utils_iplot(spectrum, *args, **kwargs): import spectrum_utils.iplot as supi with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): spectrum = _spectrum_utils_create_spectrum(spectrum, None, *args, **kwargs) return supi.spectrum(spectrum) _plot_backends = { 'default': _default_plot_spectrum, 'spectrum_utils': _spectrum_utils_plot, 'spectrum_utils.iplot': _spectrum_utils_iplot, }
[docs] def plot_spectrum(spectrum, *args, **kwargs): """ Plot a spectrum, assuming it is a dictionary containing "m/z array" and "intensity array". Parameters ---------- spectrum : dict A dictionary, as returned by pyteomics MS data parsers. Must contain "m/z array" and "intensity array" keys with decoded arrays. backend : str, keyword only, optional One of `{'default', 'spectrum_utils', 'spectrum_utils.iplot'}`. The `spectrum_utils` backend requires installing :py:mod:`spectrum_utils`. The `spectrum_utils.iplot` backend requires installing :py:mod:`spectrum_utils[iplot]`. xlabel : str, keyword only, optional Label for the X axis. Default is "m/z". ylabel : str, keyword only, optional Label for the Y axis. Default is "intensity". title : str, keyword only, optional The title. Empty by default. centroided : bool, keyword only, optional Works only for the `default` backend. If :py:const:`True` (default), peaks of the spectrum are plotted using :py:func:`pylab.bar`. If :py:const:`False`, the arrays are simply plotted using :py:func:`pylab.plot`. *args When using `default` backend: given to :py:func:`pylab.plot` or :py:func:`pylab.bar` (depending on `centroided`). **kwargs When using `default` backend: given to :py:func:`pylab.plot` or :py:func:`pylab.bar` (depending on `centroided`). min_intensity : float, keyword only, optional Remove low-intensity peaks; this is a factor of maximum peak intensity. Default is 0 (no filtering). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. max_num_peaks : int or None, keyword only, optional Remove low-intensity peaks; this is the number of peaks to keep. Default is :py:const:`None` (no filtering). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. scaling : one of `{'root', 'log', 'rank'}` or None, keyword only, optional Scaling to apply to peak intensities. Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. max_intensity : float or None, keyword only, optional Intensity of the most intense peak relative to which the peaks will be scaled (the default is :py:const:`None`, which means that no scaling relative to the most intense peak will be performed). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. Returns ------- out : matplotlib.pyplot.Axes """ bname = kwargs.pop('backend', 'default') backend = _plot_backends.get(bname) if backend is None: raise PyteomicsError('Unknown backend name: {}. Should be one of: {}.'.format( bname, '; '.join(_plot_backends))) pylab.xlabel(kwargs.pop('xlabel', 'm/z')) pylab.ylabel(kwargs.pop('ylabel', 'intensity')) if 'title' in kwargs: pylab.title(kwargs.pop('title')) return backend(spectrum, *args, **kwargs)
def _default_annotate_spectrum(spectrum, peptide, *args, **kwargs): # common kwargs types = kwargs.pop('ion_types', ('b', 'y')) aa_mass = kwargs.pop('aa_mass', mass.std_aa_mass) mass_data = kwargs.pop('mass_data', mass.nist_mass) ion_comp = kwargs.pop('ion_comp', mass.std_ion_comp) colors = { 'a': '#388E3C', 'b': '#1976D2', 'c': '#00796B', 'x': '#7B1FA2', 'y': '#D32F2F', 'z': '#F57C00', } colors.update(kwargs.pop('colors', {})) ftol = kwargs.pop('ftol', None) if ftol is None: rtol = kwargs.pop('rtol', 1e-5) text_kw = kwargs.pop('text_kw', dict(ha='center', clip_on=True, backgroundcolor='#ffffff99')) precursor_charge = kwargs.pop('precursor_charge', None) if precursor_charge is None: precursor_charge = _get_precursor_charge(spectrum) if precursor_charge is None: raise PyteomicsError('Could not extract precursor charge from spectrum. Please specify `precursor_charge` kwarg.') maxcharge = kwargs.pop('maxcharge', max(1, precursor_charge - 1)) ax = kwargs.get('ax', None) # end of common kwargs # backend-specific kwargs centroided = kwargs.pop('centroided', True) adjust = kwargs.pop('adjust_text', None) if adjust or adjust is None: try: from adjustText import adjust_text adjust_kw = kwargs.pop('adjust_kw', dict( only_move={'text': 'y', 'points': 'y', 'objects': 'y'}, autoalign=False, force_text=(1, 1))) except ImportError: if adjust: raise PyteomicsError('Install adjustText for text adjustment') adjust = False else: if adjust is None: adjust = True # end of backend-specific kwargs parsed = parser.parse(peptide, True, labels=list(aa_mass) + [parser.std_cterm, parser.std_nterm]) n = len(parsed) maxpeak = spectrum['intensity array'].max() mz, names = {}, {} for ion in types: for charge in range(1, maxcharge + 1): if ion[0] in 'abc': for i in range(2, n): mz.setdefault(ion, []).append(mass.fast_mass2(parsed[:i] + [parser.std_cterm], aa_mass=aa_mass, charge=charge, ion_type=ion, mass_data=mass_data, ion_comp=ion_comp)) names.setdefault(ion, []).append(ion[0] + str(i - 1) + ion[1:]) else: for i in range(1, n - 1): mz.setdefault(ion, []).append(mass.fast_mass2([parser.std_nterm] + parsed[n - (i + 1):], aa_mass=aa_mass, charge=charge, ion_type=ion, mass_data=mass_data, ion_comp=ion_comp)) names.setdefault(ion, []).append(ion[0] + str(i) + ion[1:]) texts = [] for ion in types: c = colors.get(ion, colors.get(ion[0], 'blue')) matrix = np.abs(spectrum['m/z array'] - np.array(mz[ion]).reshape(-1, 1)) if ftol is not None: match = np.where(matrix < ftol) else: match = np.where(matrix / spectrum['m/z array'] < rtol) pseudo_spec = {'m/z array': spectrum['m/z array'][match[1]], 'intensity array': spectrum['intensity array'][match[1]]} plot_spectrum(pseudo_spec, centroided=True, edgecolor=c, ax=ax) for j, i in zip(*match): x = spectrum['m/z array'][i] y = spectrum['intensity array'][i] + maxpeak * 0.02 name = names[ion][j] texts.append(pylab.text(x, y, name, color=c, **text_kw)) if adjust: adjust_text(texts, **adjust_kw) kwargs.setdefault('zorder', -1) return plot_spectrum(spectrum, *args, centroided=centroided, **kwargs) def _get_precursor_charge(spectrum): try: return mgf.MGFBase.parse_precursor_charge(spectrum['params']['charge'], list_only=True)[0] except (PyteomicsError, KeyError): pass try: return int(spectrum['precursorList']['precursor'][0]['selectedIonList']['selectedIon'][0]['charge state']) except KeyError: pass return None def _get_precursor_mz(spectrum): try: return spectrum['params']['pepmass'][0] except KeyError: pass try: return spectrum['precursorList']['precursor'][0]['selectedIonList']['selectedIon'][0]['selected ion m/z'] except KeyError: pass if 'attributes' in spectrum: for attr in spectrum['attributes']: if attr in {"MS:1000827", "MS:1000744", "MS:1002234"}: return spectrum['attributes'][attr] return None def _spectrum_utils_create_spectrum(spectrum, *args, **kwargs): if sus is None: raise PyteomicsError('This backend requires `spectrum_utils>=0.4`.') # backend-specific parameters mz_range = kwargs.pop('mz_range', None) min_intensity = kwargs.pop('min_intensity', 0.0) max_num_peaks = kwargs.pop('max_num_peaks', None) scaling = kwargs.pop('scaling', None) max_intensity = kwargs.pop('max_intensity', None) spectrum = sus.MsmsSpectrum( 'None', kwargs.pop('precursor_mz', None), kwargs.pop('precursor_charge', None), spectrum['m/z array'], spectrum['intensity array']) if mz_range: spectrum = spectrum.set_mz_range(*mz_range) spectrum = spectrum.filter_intensity(min_intensity=min_intensity, max_num_peaks=max_num_peaks ).scale_intensity(scaling, max_intensity) return spectrum def _spectrum_utils_annotate_spectrum(spectrum, peptide, *args, **kwargs): # common kwargs aa_mass = kwargs.pop('aa_mass', mass.std_aa_mass) types = kwargs.pop('ion_types', ('b', 'y')) tol = kwargs.pop('ftol', None) if tol is None: tol = kwargs.pop('rtol', 1e-5) * 1e6 tol_mode = 'ppm' else: tol_mode = 'Da' # kwargs.pop('text_kw', None) # not used precursor_charge = kwargs.pop('precursor_charge', None) if precursor_charge is None: precursor_charge = _get_precursor_charge(spectrum) if precursor_charge is None: raise PyteomicsError('Could not extract precursor charge from spectrum. ' 'Please specify `precursor_charge` keyword argument.') maxcharge = kwargs.pop('maxcharge', max(1, precursor_charge - 1)) # end of common kwargs # backend-specific parameters remove_precursor_peak = kwargs.pop('remove_precursor_peak', False) # peptide can be modX or proforma. spectrum_utils supports proforma only aa_comp = kwargs.get('aa_comp') mod_names = kwargs.get('mod_names') prefix = kwargs.get('prefix') try: parsed_proforma = proforma.ProForma.parse(peptide) peptide_pro = peptide except Exception: parsed_proforma = None try: peptide_pro = parser.to_proforma(peptide, aa_mass=aa_mass, aa_comp=aa_comp, mod_names=mod_names, prefix=prefix) except Exception: raise PyteomicsError("Cannot parse {} as ProForma or convert from modX".format(peptide)) precursor_mz = kwargs.pop('precursor_mz', None) if precursor_mz is None: precursor_mz = _get_precursor_mz(spectrum) if precursor_mz is None: try: if aa_comp: precursor_mz = mass.calculate_mass(peptide, aa_comp=aa_comp, charge=precursor_charge) elif not parsed_proforma: precursor_mz = mass.fast_mass2(peptide, aa_mass=aa_mass, charge=precursor_charge) else: precursor_mz = mass.mass_charge_ratio(parsed_proforma.mass, precursor_charge) except PyteomicsError: raise PyteomicsError('Cannot obtain precursor m/z, please specify `precursor_mz` argument.') spectrum = _spectrum_utils_create_spectrum(spectrum, *args, precursor_mz=precursor_mz, precursor_charge=precursor_charge, **kwargs) if remove_precursor_peak: spectrum = spectrum.remove_precursor_peak(tol, tol_mode) spectrum = spectrum.annotate_proforma(peptide_pro, tol, tol_mode, types, maxcharge) return spectrum
[docs] class SpectrumUtilsColorScheme: """Context manager that temporarily changes `spectrum_utils.plot.colors`."""
[docs] def __init__(self, colors): self.colors = colors self.previous_colors = sup.colors.copy()
def __enter__(self): if self.colors: sup.colors.update(self.colors) def __exit__(self, *args, **kwargs): sup.colors = self.previous_colors
def _spectrum_utils_annotate_plot(spectrum, peptide, *args, **kwargs): with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): spectrum = _spectrum_utils_annotate_spectrum(spectrum, peptide, *args, **kwargs) return sup.spectrum(spectrum, annot_kws=kwargs.pop('text_kw', None), ax=kwargs.pop('ax', None)) def _spectrum_utils_annotate_iplot(spectrum, peptide, *args, **kwargs): import spectrum_utils.iplot as supi with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): spectrum = _spectrum_utils_annotate_spectrum(spectrum, peptide, *args, **kwargs) return supi.spectrum(spectrum, annot_kws=kwargs.pop('text_kw', None)) _annotation_backends = { 'default': _default_annotate_spectrum, 'spectrum_utils': _spectrum_utils_annotate_plot, 'spectrum_utils.iplot': _spectrum_utils_annotate_iplot, }
[docs] def annotate_spectrum(spectrum, peptide, *args, **kwargs): """Plot a spectrum and annotate matching fragment peaks. Parameters ---------- spectrum : dict A spectrum as returned by Pyteomics parsers. Needs to have 'm/z array' and 'intensity array' keys. peptide : str A modX sequence. backend : str, keyword only, optional One of `{'default', 'spectrum_utils', 'spectrum_utils.iplot'}`. The `spectrum_utils` backend requires installing :py:mod:`spectrum_utils`. The `spectrum_utils.iplot` backend requires installing :py:mod:`spectrum_utils[iplot]`. ion_types : Container, keyword only, optional Ion types to be considered for annotation. Default is `('b', 'y')`. precursor_charge : int, keyword only, optional If not specified, an attempt is made to extract it from `spectrum`. maxcharge : int, keyword only, optional Maximum charge state for fragment ions to be considered. Default is `precursor_charge - 1`. colors : dict, keyword only, optional Keys are ion types, values are colors to plot the annotated peaks with. Default depends on backend. ftol : float, keyword only, optional A fixed m/z tolerance value for peak matching. Alternative to `rtol`. rtol : float, keyword only, optional A relative m/z error for peak matching. Default is 10 ppm. aa_mass : dict, keyword only, optional A dictionary of amino acid residue masses. text_kw : dict, keyword only, optional Keyword arguments for :py:func:`pylab.text`. xlabel : str, keyword only, optional Label for the X axis. Default is "m/z". Does not work with `spectrum_utils.iplot` backend. ylabel : str, keyword only, optional Label for the Y axis. Default is "intensity". Does not work with `spectrum_utils.iplot` backend. title : str, keyword only, optional The title. Empty by default. Does not work with `spectrum_utils.iplot` backend. ax : matplotlib.pyplot.Axes, keyword only, optional Axes to draw the spectrum. Does not work with `spectrum_utils.iplot` backend. *args Passed to the plotting backend. **kwargs Passed to the plotting backend. centroided : bool, keyword only, optional Passed to :py:func:`plot_spectrum`. Only works with `default` backend. ion_comp : dict, keyword only, optional A dictionary defining ion compositions to override :py:const:`pyteomics.mass.std_ion_comp`. Only works with `default` backend. mass_data : dict, keyword only, optional A dictionary of element masses to override :py:const:`pyteomics.mass.nist_mass`. Only works with `default` backend. adjust_text : bool, keyword only, optional Adjust the overlapping text annotations using :py:mod:`adjustText`. Only works with `default` backend. adjust_kw : dict, keyword only, optional Keyword arguments for :py:func:`adjust_text`. Only works with `default` backend. remove_precursor_peak : bool, keyword only, optional Remove precursor peak from spectrum before annotation. Default is :py:const:`False`. Only works with `spectrum_utils` backend. min_intensity : float, keyword only, optional Remove low-intensity peaks; this is a factor of maximum peak intensity. Default is 0 (no filtering). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. max_num_peaks : int or None, keyword only, optional Remove low-intensity peaks; this is the number of peaks to keep. Default is :py:const:`None` (no filtering). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. scaling : one of `{'root', 'log', 'rank'}` or None, keyword only, optional Scaling to apply to peak intensities. Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. max_intensity : float or None, keyword only, optional Intensity of the most intense peak relative to which the peaks will be scaled (the default is :py:const:`None`, which means that no scaling relative to the most intense peak will be performed). Only works with `spectrum_utils` and `spectrum_utils.iplot` backends. aa_comp : dict, keyword only, optional Amino acid compositions, including modified ones. If given, will be used for conversion from *modX* to ProForma. mod_names : dict or callable, keyword only, optional If given, will be used for conversion from *modX* to ProForma. prefix : str, keyword only, optional If given, will be used for conversion from *modX* to ProForma. Returns ------- out : matplotlib.pyplot.Axes """ bname = kwargs.pop('backend', 'default') backend = _annotation_backends.get(bname) if backend is None: raise PyteomicsError('Unknown backend name: {}. Should be one of: {}.'.format( bname, '; '.join(_annotation_backends))) pylab.xlabel(kwargs.pop('xlabel', 'm/z')) pylab.ylabel(kwargs.pop('ylabel', 'intensity')) pylab.title(kwargs.pop('title', '')) return backend(spectrum, peptide, *args, **kwargs)
def _spectrum_utils_mirror(spec_top, spec_bottom, spectrum_kws=None, ax=None, **kwargs): with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): ax = sup.mirror(spec_top, spec_bottom, spectrum_kws=spectrum_kws, ax=ax) ax.set_xlabel(kwargs.pop('xlabel', 'm/z')) ax.set_ylabel(kwargs.pop('ylabel', 'intensity')) ax.set_title(kwargs.pop('title', '')) return ax def _spectrum_utils_iplot_mirror(spec_top, spec_bottom, spectrum_kws=None, **kwargs): import spectrum_utils.iplot as supi with SpectrumUtilsColorScheme(kwargs.pop('colors', None)): return supi.mirror(spec_top, spec_bottom, spectrum_kws=spectrum_kws) _mirror_backends = { 'spectrum_utils': _spectrum_utils_mirror, 'spectrum_utils.iplot': _spectrum_utils_iplot_mirror, }
[docs] def mirror(spec_top, spec_bottom, peptide=None, spectrum_kws=None, ax=None, **kwargs): """Create a mirror plot of two (possible annotated) spectra using `spectrum_utils`. Parameters ---------- spec_top : dict A spectrum as returned by Pyteomics parsers. Needs to have 'm/z array' and 'intensity array' keys. spec_bottom : dict A spectrum as returned by Pyteomics parsers. Needs to have 'm/z array' and 'intensity array' keys. peptide : str or None, optional A modX sequence or ProForma. If provided, the peaks will be annotated as peptide fragments. spectrum_kws : dict or None, optional Passed to :py:func:`spectrum_utils.plot.mirror`. backend : str, keyword only, optional One of {'spectrum_utils', 'spectrum_utils.iplot'}. Default is 'spectrum_utils'. .. note :: Requires :py:mod:`spectrum_utils` or :py:mod:`spectrun_utils[iplot]`, respectively. ax : matplotlib.pyplot.Axes or None, optional Passed to :py:func:`spectrum_utils.plot.mirror`. Works only for the 'spectrum_utils' backend. xlabel : str, keyword only, optional Label for the X axis. Default is "m/z". Works only for the 'spectrum_utils' backend. ylabel : str, keyword only, optional Label for the Y axis. Default is "intensity". Works only for the 'spectrum_utils' backend. title : str, keyword only, optional The title. Empty by default. Works only for the 'spectrum_utils' backend. **kwargs : same as for :py:func:`annotate_spectrum` for `spectrum_utils` backends. Returns ------- out : matplotlib.pyplot.Axes """ spec_gen = _spectrum_utils_create_spectrum if peptide is None else _spectrum_utils_annotate_spectrum spec_top = spec_gen(spec_top, peptide, **kwargs) spec_bottom = spec_gen(spec_bottom, peptide, **kwargs) bname = kwargs.pop('backend', 'spectrum_utils') backend = _mirror_backends.get(bname) if backend is None: raise PyteomicsError('Unknown backend name: {}. Should be one of: {}.'.format( bname, '; '.join(_mirror_backends))) backend_kw = {'spectrum_kws': spectrum_kws} if bname == 'spectrum_utils': backend_kw['ax'] = ax backend_kw.update(kwargs) return backend(spec_top, spec_bottom, **backend_kw)

Contents