From bd1c9d5cf19eaee97e135616344beeed965a090e Mon Sep 17 00:00:00 2001 From: Ralf Gabriels Date: Thu, 6 Jul 2023 16:39:24 +0200 Subject: [PATCH] Add functionality for plotting mass errors (#46) * Add mass errors plot * Set intensity ylim to 1.1 to avoid annotation overflow * Add plot_unknown argument to mass_errors * Add reference * Implement requested changes * Add figure-level plot.full_mirror * Implement requested changes * Add documentation for mass_errors and facet to plotting.md * Implement requested changes: use width instead of aspect ratio; fix docs figure filename * Fix docs figure alt text * Update docs to facet width kwarg change --- docs/src/facet.png | Bin 0 -> 89287 bytes docs/src/mass_errors.png | Bin 0 -> 34589 bytes docs/src/plotting.md | 71 ++++++++++- spectrum_utils/plot.py | 259 ++++++++++++++++++++++++++++++++++++--- spectrum_utils/utils.py | 45 +++++++ 5 files changed, 355 insertions(+), 20 deletions(-) create mode 100644 docs/src/facet.png create mode 100644 docs/src/mass_errors.png diff --git a/docs/src/facet.png b/docs/src/facet.png new file mode 100644 index 0000000000000000000000000000000000000000..e99fc307382ce8a4030220860a543f4432a61a62 GIT binary patch literal 89287 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

Yru44sT6cg93R8?wECu$WVd3%ShZBMBQ2P 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

t+5K&lA62C;q&J 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

    h43cw2YZW34OO?6abk^NJGY%x z#NTj;wDWU?pEc?Gu*UljOA$#4bko?iN0R8Kta{;iD~Z4m?VXAU45gBYY>T5c`4~VP z(t(?ol<4G+L{bcoz`k_e$ifXcZe5({lmfl43TLyMhn{aLKbn8FE)t-0Qly{Dr$j$APd~yh30_d!Op;# zu$(7?UzRQvd>?A#G4UIVpaYWoIaj?nr>kJtAB}6K3^TvY79C}zLHq(~w85}OO6!aI zkm;1N(ePH@sjN5LvVD;|7H&t}Hl0g*u&+Kkq`41fL74g3XN&SLVZ~sp384Iu`|zpa zAVetmkk9!Zr_y&RsRllY<*c<=6bxF z#_X>?nclXmOIx%zB`O&M3!KZW@W$?R*a4w8Ov}%HwDIu(SZn`6lfe}JMt^iG5X0`8 zJkk#OYK6x@-mzcT{j(j?&I8h_=?m<+mstUggD6OhsUo-xvcY;}r{E!iWJ{sKG zfVvS@hWg2o{kcd;_Rzg0R9<;YXou2N4hT%JaTrH>k2{!|6X0^w64MBbBHzvB9OMfC zetUBqba!_=PbgNI*Ro=wTrk^HCIC zRIBo$@Kit6dXGkMPoA8sDR`QAa7*wVRtt9@RW3n>4FfM9Upxp&WaB+CGw^-lF-G99 zNSaH+D-?20!F@5aS8-)~;EAOo9;pcGtuyAKX8a$VH9d1ZyVQ~Sz;R`1khg#+XT&qa z*_FD~P7ZYVeK4L?7VkxJAFV<*Zp{SeY0}@S{QpE``dDK4lm-;yB+{_kXL^t^&=zQh zdYqgzDP}U6w<=#P*YkRT4FuW!uL79=UC{W`-EIyqm8rU#c4XP$-@?p6y$6dge=my zAaz=8EY28X10sP!*DJ@P!4+;=vn&8L>NZB0#RY0y*cnXwmMY*Cqr;yx4h=sZ8IaBc zS=^SiJLhJONXK*hwG0R^=)llHpTd__>k;t&O*iW3`Ty8s)=0ZK5W4MF}wK=Dx~P{ z+x>0c{joLAI1%f3<>U9*WQuv}MA*#!`qup%_K{~hO_M|AhBXvUFP{xh^g#o^Gf)D2EQF5ZNkd%d>PPX~Wy&Q@y$Hj#+v1lqOCwxmnJs z%7v(#NbkdWg%A&F4kl`j7L1o)RMo^y14u$_C~0Kg3MDo)qJstJg9CNjo<43gy#rCO zJabPbUox7;4YKI7hls`TbQEqdjc#Iz%h_}|o0(!ebdY#rSHoNaC1qk=%!EbYzsqGz z)6FNo!`!K;g>CLEplw0+182xv)I~8_1gGPEt=0!dD7+b%l(ta!daM@Y(Pu$Q(=@gz zX}E6Mmui$mY*64DZrgZcZqv^C6>3&vJn+?6D_A_7SA@-ox0$|uhjIe_0o5JmLfwe? z8*0}>3%-Vq-{?0D9M&aJHB{#vsbt^ro_AAgu_6F^|kG#u>jp zG+pOlnx7g~F@XFHaU1R{;}m0GURU&N^LxQS-t^UJ+osOdEvJwRlI)eEB;BGpsJU|3 zp$T~1s#$q~_1ExZY{mFDjW?_0o)6=I;F4!;SBt@_G{ z?6A&X+2`RSmJjz9IL*4`X;_DB5*XARl$uQ4M#c#WaZdu>^$g&dk$EqnE8C8#S%jmS zZOG^D#`DbLbln{Yf$MWVTsfrL3~mG- zO=6%Stz_H2$p|A}r6n?d@)hKZz>$Pp5!{UwQFD*4zBMzj@93G!8mw81i-8kh$CBtR zfMT?LNTRLLU5;bIs8}(JOeU1^)pZK>?G@T{f%sH$YJ-~X*zMRYF!zmJb7nQ28mcGt zA~{7y;K3-n%-XHq+ebrYIVR+P8&7{gVaO>i&D(57q`0}%wFstI z7s3*0jA#dOkAw8v(Bp;XM#6dHXA&MV_Zn3DJ^Ot;+O@lIehN6RjbyAn0aoYz;eG=Qk}?kxEHdVl!*cAeVADs4t&tfP&pFV1TV*NYp> zdI8eb>J`hQFwoyQY!g0{cW!DvO*@GeGTIWWbS+scSm5-N%4NAF@e^(0|GDBKay0WGB*P$%$vJ%$Zio;1kPads9?>`qewz zc3!_y6sbfp+SD1e7|?BIPx8)|Vw+qqgn^#_icE=~&-S_i)|#;&KTWz?sh*9vVQDwV zI!=}2Mredxsf*$Zs$n~AMt<^)OBAjqoe^{2&V3KonLA|LVB-BysMMIb9zv0M(=GnClJ)kp1X&P*XE{#y$pAqaI{X;m(L)a@FWt;qqs?O z3w!k{&+NL=k~6bjX4T3uK7~pgE7OxOt8`qjv@5mhki>a?C3wNIW?3>)>kaNd5skZZ z;ATOGrv{SuB8%pLai=8qGM*;HjSd|or`yT}7$^A@=a+|~EBn;4N%NjC7&_Q!nT^(O z`_6yo?L{jxPtc9pu<9{rPq2BABT>!p@H+%~W)C()=h2HtjOi!WL!M8$F$UCD`mbla znWN9D3EBajOP~W%G&{I#5PCX0U(LSZq`SDrp&8Mg=3sUyP$U6^PLk}fX`b#J68P+V@Z#>0 zk)U-!N|i-Pd-vh}RehGXJ!{q+HSc=A>WCYeH|+<+IjF>`(Bpn;fWAU~u37AsLE2iT z+Jg)e0tGWdJ&6$kIP`L)ebo(guS%RC_t zz4aQ=NOuq~Dz;;lefo16rvP!Sa%b1rcZ3(_hu@8C!v;0&4m8rrB?@wcr{n`eB4|cru9HwjIV9b% z$TPk?6_m2xw{hxOY}(!AUSP^@%5FO*boYE9s>JyH^e~Ml#6V6KA&gY;Al2Kt9CwW>wA({SZ4v!!H1M%M1j{pDw literal 0 HcmV?d00001 diff --git a/docs/src/mass_errors.png b/docs/src/mass_errors.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d44d70fc1eeff32c5a8968b1efe066ea85a2ab GIT binary patch literal 34589 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 literal 0 HcmV?d00001 diff --git a/docs/src/plotting.md b/docs/src/plotting.md index 6cad870..603d789 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -9,7 +9,7 @@ Some of the arguments that can be provided to `spectrum_utils.plot.spectrum(...) - `color_ions`: Boolean flag indicating whether the annotated peaks should be colored. - `annot_fmt`: A function that converts a `FragmentAnnotation` to a label to annotate the corresponding peak (see below). - `annot_kws`: A dictionary with options to customize peak label texts. -See the [`matplotlib.text.Text` documentation](https://matplotlib.org/3.1.1/api/text_api.html#matplotlib.text.Text) for available options. + See the [`matplotlib.text.Text` documentation](https://matplotlib.org/3.1.1/api/text_api.html#matplotlib.text.Text) for available options. - `grid`: Enable/disable the grid. See the [API reference](api.md) for full details on how to use these settings. @@ -121,6 +121,75 @@ plt.close() All of the advanced plotting arguments described above can be provided for the mirror plot as well using the `spectrum_kws` argument. +## Mass error plot + +The difference between the observed and the theoretical mass of annotated fragment ions can be visualized in a mass error plot. In these bubble plots, the size of the bubbles corresponds to the intensity of the fragment ions, the x-axis shows the observed _m/z_, and the y-axis shows the mass error either ppm or in Dalton. Use `spectrum_utils.plot.mass_errors(...)` to plot mass errors: + +```python +import matplotlib.pyplot as plt +import spectrum_utils.plot as sup +import spectrum_utils.spectrum as sus + +usi = "mzspec:PXD022531:j12541_C5orf38:scan:12368" +peptide = "VAATLEILTLK/2" +spectrum = sus.MsmsSpectrum.from_usi(usi) +spectrum.annotate_proforma( + peptide, + fragment_tol_mass=0.05, + fragment_tol_mode="Da", + ion_types="aby", + max_ion_charge=2, + neutral_losses={"NH3": -17.026549, "H2O": -18.010565}, +) + +fig, ax = plt.subplots(figsize=(10.5, 3)) +sup.mass_errors(spectrum, plot_unknown=False, ax=ax) +plt.savefig("mass_errors.png", dpi=300, bbox_inches="tight", transparent=True) +plt.close() +``` + +![Mass error plot](mass_errors.png) + +## Figure-level facet plot + +The figure-level `spectrum_utils.plot.facet` function combines the `spectrum_utils.plot.mirror` and `spectrum_utils.plot.mass_errors` functionality: + +```python +import matplotlib.pyplot as plt +import spectrum_utils.plot as sup +import spectrum_utils.spectrum as sus + +peptide = "VAATLEILTLK/2" +annotation_settings = { + "fragment_tol_mass": 0.05, + "fragment_tol_mode": "Da", + "ion_types": "aby", + "max_ion_charge": 2, + "neutral_losses": {"NH3": -17.026549, "H2O": -18.010565}, +} + +usi_top = "mzspec:PXD022531:j12541_C5orf38:scan:12368" +spectrum_top = sus.MsmsSpectrum.from_usi(usi_top) +spectrum_top.annotate_proforma(peptide, **annotation_settings) + +usi_bottom = "mzspec:PXD022531:b11156_PRAMEF17:scan:22140" +spectrum_bottom = sus.MsmsSpectrum.from_usi(usi_bottom) +spectrum_bottom.annotate_proforma(peptide, **annotation_settings) + +fig = sup.facet( + spec_top=spectrum_top, + spec_mass_errors=spectrum_top, + spec_bottom=spectrum_bottom, + mass_errors_kws={"plot_unknown": False}, + height=7, + width=10.5, +) +plt.savefig("facet.png", dpi=300, bbox_inches="tight", transparent=True) +plt.close() +``` + +![Facet plot](facet.png) + ## Interactive plotting Besides the standard plotting functionality in `spectrum_utils.plot`, spectrum_utils also contains interactive plotting functionality in `spectrum_utils.iplot`. diff --git a/spectrum_utils/plot.py b/spectrum_utils/plot.py index 408eca0..0cbac91 100755 --- a/spectrum_utils/plot.py +++ b/spectrum_utils/plot.py @@ -1,13 +1,24 @@ import functools import itertools import math -from typing import Callable, Dict, Iterable, Optional, Tuple, Union +from typing import ( + Any, + Callable, + Dict, + Iterable, + Mapping, + Optional, + Tuple, + Union, +) import matplotlib.pyplot as plt import matplotlib.ticker as mticker +import numpy as np import spectrum_utils.fragment_annotation as fa from spectrum_utils.spectrum import MsmsSpectrum +from spectrum_utils.utils import da_to_ppm, ppm_to_da colors = { @@ -40,6 +51,31 @@ } +def _format_ax( + ax: plt.Axes, + grid: Union[bool, str], +): + """Set ax formatting options that are common to all plot types.""" + ax.xaxis.set_minor_locator(mticker.AutoLocator()) + ax.yaxis.set_minor_locator(mticker.AutoLocator()) + ax.xaxis.set_minor_locator(mticker.AutoMinorLocator()) + ax.yaxis.set_minor_locator(mticker.AutoMinorLocator()) + if grid in (True, "both", "major"): + ax.grid(True, "major", color="#9E9E9E", linewidth=0.2) + if grid in (True, "both", "minor"): + ax.grid(True, "minor", color="#9E9E9E", linewidth=0.2) + ax.set_axisbelow(True) + ax.tick_params(axis="both", which="both", labelsize="small") + ax.set_xlabel("m/z", style="italic") + + +def _get_xlim(spec: MsmsSpectrum) -> Tuple[float, float]: + """Get plot x-axis limits for a given spectrum.""" + round_mz = 50 + max_mz = math.ceil(spec.mz[-1] / round_mz + 1) * round_mz + return 0.0, max_mz + + def _annotate_ion( mz: float, intensity: float, @@ -167,30 +203,15 @@ def spectrum( if ax is None: ax = plt.gca() + _format_ax(ax, grid) ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0)) - ax.set_ylim(*(0, 1) if not mirror_intensity else (-1, 0)) - - ax.xaxis.set_minor_locator(mticker.AutoLocator()) - ax.yaxis.set_minor_locator(mticker.AutoLocator()) - ax.xaxis.set_minor_locator(mticker.AutoMinorLocator()) - ax.yaxis.set_minor_locator(mticker.AutoMinorLocator()) - if grid in (True, "both", "major"): - ax.grid(True, "major", color="#9E9E9E", linewidth=0.2) - if grid in (True, "both", "minor"): - ax.grid(True, "minor", color="#9E9E9E", linewidth=0.2) - ax.set_axisbelow(True) - - ax.tick_params(axis="both", which="both", labelsize="small") - - ax.set_xlabel("m/z", style="italic") + ax.set_ylim(*(0, 1.15) if not mirror_intensity else (-1.15, 0)) ax.set_ylabel("Intensity") if len(spec.mz) == 0: return ax - round_mz = 50 - max_mz = math.ceil(spec.mz[-1] / round_mz + 1) * round_mz - ax.set_xlim(0, max_mz) + ax.set_xlim(*_get_xlim(spec)) max_intensity = spec.intensity.max() annotations = ( @@ -227,6 +248,129 @@ def spectrum( return ax +def mass_errors( + spec: MsmsSpectrum, + *, + unit: Optional[str] = None, + plot_unknown: bool = True, + color_ions: bool = True, + grid: Union[bool, str] = True, + ax: Optional[plt.Axes] = None, +) -> plt.Axes: + """ + Plot mass error bubble plot for a given spectrum. + + A mass error bubble plot shows the error between observed and theoretical + mass (y-axis) in function of the **m/z** (x-axis) for each peak in the + spectrum. The size of the bubble is proportional to the intensity of the + peak. + + Parameters + ---------- + spec : MsmsSpectrum + The spectrum with mass errors to be plotted. + unit : str, optional + The unit of the mass errors, either 'ppm', 'Da', or None. If None, + the unit that was used for spectrum annotation is used. The default is + None. + plot_unknown : bool, optional + Flag indicating whether or not to plot mass errors for unknown peaks. + color_ions : bool, optional + Flag indicating whether or not to color dots for annotated fragment + ions. The default is True. + grid : Union[bool, str], optional + Draw grid lines or not. Either a boolean to enable/disable both major + and minor grid lines or 'major'/'minor' to enable major or minor grid + lines respectively. + ax : Optional[plt.Axes], optional + Axes instance on which to plot the mass errors. If None the current + Axes instance is used. + + Returns + ------- + plt.Axes + The matplotlib Axes instance on which the mass errors are plotted. + + Notes + ----- + The mass error bubble plot was first introduced in [1]_. + + References + ---------- + .. [1] Barsnes,H., Eidhammer,I. and Martens,L. (2010) + FragmentationAnalyzer: An open-source tool to analyze MS/MS + fragmentation data. PROTEOMICS, 10, 1087–1090. + doi:10.1002/pmic.200900681 + + """ + if ax is None: + ax = plt.gca() + + _format_ax(ax, grid) + + if len(spec.mz) == 0: + ax.set_ylabel("Mass error") + ax.set_ylim(-1, 1) + return ax + + annotations = ( + spec.annotation + if spec.annotation is not None + else itertools.repeat(None, len(spec.mz)) + ) + + known_ions = [] + dot_colors = [] + mz_deltas = [] + mz_delta_units = [] + for ann in annotations: + # Use the first annotation in case there are multiple options. + ion_type = ann[0].ion_type[0] if ann is not None else None + is_known_ion = ion_type is not None and ion_type != "?" + known_ions.append(is_known_ion) + dot_colors.append(colors.get(ion_type if color_ions else None)) + mz_deltas.append(ann[0].mz_delta[0] if is_known_ion else 0.0) + mz_delta_units.append(ann[0].mz_delta[1] if is_known_ion else None) + + dot_colors = np.array(dot_colors) + mz_deltas = np.array(mz_deltas) + intensity_scaled = 500 * (spec.intensity / np.max(spec.intensity)) + mask = ( + np.ones_like(spec.mz, dtype=bool) + if plot_unknown + else np.array(known_ions) + ) + + for known_unit in ["ppm", "Da"]: + # Use `not any` instead of `all` to fail fast + if not any(u and u != known_unit for u in mz_delta_units): + annotation_unit = known_unit + break + else: + raise ValueError("Inconsistent or unknown mass units in annotations.") + if unit == "Da" and annotation_unit == "ppm": + mz_deltas = ppm_to_da(mz_deltas, spec.mz) + elif unit == "ppm" and annotation_unit == "Da": + mz_deltas = da_to_ppm(mz_deltas, spec.mz) + + y_lim = 1.2 * np.max(np.abs(mz_deltas)) + if y_lim > 0.0: + ax.set_ylim(-y_lim, y_lim) + ax.set_xlim(*_get_xlim(spec)) + ax.set_ylabel(f"Mass error ({unit or annotation_unit})") + + ax.scatter( + spec.mz[mask], + mz_deltas[mask], + s=intensity_scaled[mask], + c=dot_colors[mask], + alpha=0.5, + edgecolors="none", + ) + + return ax + + def mirror( spec_top: MsmsSpectrum, spec_bottom: MsmsSpectrum, @@ -286,3 +430,80 @@ def mirror( ) return ax + + +def facet( + spec_top: MsmsSpectrum, + spec_mass_errors: Optional[MsmsSpectrum] = None, + spec_bottom: Optional[MsmsSpectrum] = None, + spectrum_kws: Optional[Mapping[str, Any]] = None, + mass_errors_kws: Optional[Mapping[str, Any]] = None, + height: Optional[float] = None, + width: Optional[float] = None, +) -> plt.Figure: + """ + Plot a spectrum, and optionally mass errors, and a mirror spectrum. + + Parameters + ---------- + spec_top : MsmsSpectrum + The spectrum to be plotted on the top. + spec_mass_errors : Optional[MsmsSpectrum], optional + The spectrum for which mass errors are to be plotted in the middle. + spec_bottom : Optional[MsmsSpectrum], optional + The spectrum to be plotted on the bottom. + spectrum_kws : Optional[Mapping[str, Any]], optional + Keyword arguments for `plot.spectrum` for the top and bottom spectra. + mass_errors_kws : Optional[Mapping[str, Any]], optional + Keyword arguments for `plot.mass_errors`. + height : Optional[float], optional + The height of the figure in inches. + width : Optional[float], optional + The width of the figure in inches. + + Returns + ------- + plt.Figure + The matplotlib Figure instance on which the spectra and mass errors + are plotted. + """ + + n_rows = 1 + (spec_mass_errors is not None) + (spec_bottom is not None) + height_ratios = [1] + if spec_mass_errors is not None: + height_ratios.append(0.5) + if spec_bottom is not None: + height_ratios.append(1) + + fig, axes = plt.subplots( + *(n_rows, 1), + figsize=(width or 7.5, height or (3.75 if spec_bottom is None else 6)), + sharex=True, + gridspec_kw={"height_ratios": height_ratios}, + ) + axes = np.array(axes).flatten() + + spectrum(spec_top, ax=axes[0], **spectrum_kws or {}) + + if spec_mass_errors is not None: + mass_errors(spec_mass_errors, ax=axes[1], **mass_errors_kws or {}) + axes[0].get_xaxis().get_label().set_visible(False) + + if spec_bottom is not None: + spectrum( + spec_bottom, + mirror_intensity=True, + ax=axes[-1], + **spectrum_kws or {}, + ) + for ax in axes[:-1]: + ax.get_xaxis().get_label().set_visible(False) + + axes[-1].yaxis.set_major_formatter( + mticker.FuncFormatter(lambda x, pos: f"{abs(x):.0%}") + ) + + fig.align_ylabels(axes) + fig.tight_layout() + + return fig diff --git a/spectrum_utils/utils.py b/spectrum_utils/utils.py index 968e164..4c90f63 100644 --- a/spectrum_utils/utils.py +++ b/spectrum_utils/utils.py @@ -1,4 +1,7 @@ +from typing import Union + import numba as nb +import numpy as np @nb.njit(fastmath=True, cache=True) @@ -20,3 +23,45 @@ def mass_diff(mz1, mz2, mode_is_da): The mass difference(s) between the given m/z values. """ return mz1 - mz2 if mode_is_da else (mz1 - mz2) / mz2 * 10**6 + + +def da_to_ppm( + delta_mz: Union[int, np.ndarray], mz: Union[int, np.ndarray] +) -> Union[int, np.ndarray]: + """ + Convert a mass difference in Dalton to ppm. + + Parameters + ---------- + delta_mz : int or np.ndarray + Mass difference in Dalton. + mz : int or np.ndarray + m/z value of peak. + + Returns + ------- + int or np.ndarray + + """ + return delta_mz / mz * 1e6 + + +def ppm_to_da( + delta_mz: Union[int, np.ndarray], mz: Union[int, np.ndarray] +) -> Union[int, np.ndarray]: + """ + Convert a mass difference in ppm to Dalton. + + Parameters + ---------- + delta_mz : int or np.ndarray + Mass difference in ppm. + mz : int or np.ndarray + m/z value of peak. + + Returns + ------- + int or np.ndarray + + """ + return delta_mz / 1e6 * mz