Interactive plots

With special plotting libraries like holoviews and datashader for big data visualization as well as bokeh for interactivenss, we can use the functionality of pyopenms to quickly create fully interactive views of mass spectrometry data. Here we plot a full map of MS1 that can be interactively zoomed-in if you execute the code in a notebook (e.g. on Binder, see the button on top of the page).

 1    from pyopenms import *
 2    import pandas as pd
 3    import numpy as np
 4    import datashader as ds
 5    import holoviews as hv
 6    import holoviews.operation.datashader as hd
 7    from holoviews.plotting.util import process_cmap
 8    from holoviews import opts, dim
 9    import sys
10
11    hv.extension('bokeh')
12
13    exp = MSExperiment() # type: PeakMap
14    loader = MzMLFile()
15    loadopts = loader.getOptions()  # type: PeakFileOptions
16    loadopts.setMSLevels([1])
17    loadopts.setSkipXMLChecks(True)
18    loadopts.setIntensity32Bit(True)
19    loadopts.setIntensityRange(DRange1(DPosition1(5000), DPosition1(sys.maxsize)))
20    loader.setOptions(loadopts)
21    loader.load("../../src/data/BSA1.mzML", exp)
22    exp.updateRanges()
23    expandcols = ["RT", "mz", "inty"]
24    spectraarrs2d = exp.get2DPeakDataLong(exp.getMinRT(), exp.getMaxRT(), exp.getMinMZ(), exp.getMaxMZ())
25    spectradf = pd.DataFrame(dict(zip(expandcols, spectraarrs2d)))
26    spectradf = spectradf.set_index(["RT","mz"])
27
28    maxrt = spectradf.index.get_level_values(0).max()
29    minrt = spectradf.index.get_level_values(0).min()
30    maxmz = spectradf.index.get_level_values(1).max()
31    minmz = spectradf.index.get_level_values(1).min()
32
33    def new_bounds_hook(plot, elem):
34        x_range = plot.state.x_range
35        y_range = plot.state.y_range
36        x_range.bounds = minrt, maxrt
37        y_range.bounds = minmz, maxmz
38
39    points = hv.Points(spectradf, kdims=['RT', 'mz'], vdims=['inty'], label="MS1 survey scans").opts(
40        fontsize={'title': 16, 'labels': 14, 'xticks': 6, 'yticks': 12},
41        color=np.log(dim('int')),
42        colorbar=True,
43        cmap='Magma',
44        width=1000,
45        height=1000,
46        tools=['hover'])
47
48    raster = hd.rasterize(points, cmap=process_cmap("blues", provider="bokeh"), aggregator=ds.sum('inty'),
49                          cnorm='log', alpha=10, min_alpha=0
50            ).opts(
51                active_tools=['box_zoom'],
52                tools=['hover'],
53                hooks=[new_bounds_hook]
54            ).opts(  # weird.. I have no idea why one has to do this. But with one opts you will get an error
55                plot=dict(
56                    width=800,
57                    height=800,
58                    xlabel="Retention time (s)",
59                    ylabel="mass/charge (Da)"
60                )
61            )
62
63    hd.dynspread(raster, threshold=0.7, how="add", shape="square")
_images/bokehms1.png

With this you can also easily create whole dashboards like the one hosted here on a Binder instance. If you are reading/executing this on Binder already, execute the next cell to get a link to your current instance.

import os
from IPython.display import Markdown as md

md("When you are in binder already, you can quickly open the app [here]({}/msbokehapps).".format(os.getenv("JUPYTERHUB_SERVICE_PREFIX")))