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")
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")))