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:

../_images/bokehms1.png

With this you can also easily create whole dashboards.