Interactive Plots#
With special plotting libraries like holoviews and datashader for big
data visualization as well as bokeh for interactiveness, 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.
1import pyopenms as oms
2import pandas as pd
3import numpy as np
4import datashader as ds
5import holoviews as hv
6import holoviews.operation.datashader as hd
7from holoviews.plotting.util import process_cmap
8from holoviews import opts, dim
9
10hv.extension("bokeh")
11
12exp = oms.MSExperiment() # type: PeakMap
13loader = oms.MzMLFile()
14loadopts = loader.getOptions() # type: PeakFileOptions
15loadopts.setMSLevels([1])
16loadopts.setSkipXMLChecks(True)
17loadopts.setIntensity32Bit(True)
18loader.setOptions(loadopts)
19loader.load("../../../src/data/BSA1.mzML", exp)
20
21# Filter out low-intensity peaks using ThresholdMower
22threshold_filter = oms.ThresholdMower()
23params = threshold_filter.getDefaults()
24params.setValue(b"threshold", 5000.0)
25threshold_filter.setParameters(params)
26threshold_filter.filterPeakMap(exp)
27
28exp.updateRanges()
29expandcols = ["RT", "mz", "inty"]
30spectraarrs2d = exp.get2DPeakDataLong(
31 exp.getMinRT(), exp.getMaxRT(), exp.getMinMZ(), exp.getMaxMZ(), 1
32)
33spectradf = pd.DataFrame(dict(zip(expandcols, spectraarrs2d)))
34spectradf = spectradf.set_index(["RT", "mz"])
35
36maxrt = spectradf.index.get_level_values(0).max()
37minrt = spectradf.index.get_level_values(0).min()
38maxmz = spectradf.index.get_level_values(1).max()
39minmz = spectradf.index.get_level_values(1).min()
40
41
42def new_bounds_hook(plot, elem):
43 x_range = plot.state.x_range
44 y_range = plot.state.y_range
45 x_range.bounds = minrt, maxrt
46 y_range.bounds = minmz, maxmz
47
48
49points = hv.Points(
50 spectradf, kdims=["RT", "mz"], vdims=["inty"], label="MS1 survey scans"
51).opts(
52 fontsize={"title": 16, "labels": 14, "xticks": 6, "yticks": 12},
53 color=np.log(dim("int")),
54 colorbar=True,
55 cmap="Magma",
56 width=1000,
57 height=1000,
58 tools=["hover"],
59)
60
61raster = (
62 hd.rasterize(
63 points,
64 cmap=process_cmap("blues", provider="bokeh"),
65 aggregator=ds.sum("inty"),
66 cnorm="log",
67 alpha=10,
68 min_alpha=0,
69 )
70 .opts(active_tools=["box_zoom"], tools=["hover"], hooks=[new_bounds_hook])
71)
72
73hd.dynspread(raster, threshold=0.7, how="add", shape="square").opts(
74 width=800,
75 height=800,
76 xlabel="Retention time (s)",
77 ylabel="mass/charge (Da)",
78)
Result:
With this you can also easily create whole dashboards.