Skip to content

Latest commit

 

History

History
92 lines (74 loc) · 3.2 KB

interactive_plots.rst

File metadata and controls

92 lines (74 loc) · 3.2 KB

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

    from pyopenms import *
    import pandas as pd
    import numpy as np
    import datashader as ds
    import holoviews as hv
    import holoviews.operation.datashader as hd
    from holoviews.plotting.util import process_cmap
    from holoviews import opts, dim
    import sys

    hv.extension('bokeh')

    exp = MSExperiment() # type: PeakMap
    loader = MzMLFile()
    loadopts = loader.getOptions()  # type: PeakFileOptions
    loadopts.setMSLevels([1])
    loadopts.setSkipXMLChecks(True)
    loadopts.setIntensity32Bit(True)
    loadopts.setIntensityRange(DRange1(DPosition1(5000), DPosition1(sys.maxsize)))
    loader.setOptions(loadopts)
    loader.load("../../src/data/BSA1.mzML", exp)
    exp.updateRanges()
    expandcols = ["RT", "mz", "inty"]
    spectraarrs2d = exp.get2DPeakDataLong(exp.getMinRT(), exp.getMaxRT(), exp.getMinMZ(), exp.getMaxMZ())
    spectradf = pd.DataFrame(dict(zip(expandcols, spectraarrs2d)))
    spectradf = spectradf.set_index(["RT","mz"])

    maxrt = spectradf.index.get_level_values(0).max()
    minrt = spectradf.index.get_level_values(0).min()
    maxmz = spectradf.index.get_level_values(1).max()
    minmz = spectradf.index.get_level_values(1).min()

    def new_bounds_hook(plot, elem):
        x_range = plot.state.x_range
        y_range = plot.state.y_range
        x_range.bounds = minrt, maxrt
        y_range.bounds = minmz, maxmz

    points = hv.Points(spectradf, kdims=['RT', 'mz'], vdims=['inty'], label="MS1 survey scans").opts(
        fontsize={'title': 16, 'labels': 14, 'xticks': 6, 'yticks': 12},
        color=np.log(dim('int')),
        colorbar=True,
        cmap='Magma',
        width=1000,
        height=1000,
        tools=['hover'])

    raster = hd.rasterize(points, cmap=process_cmap("blues", provider="bokeh"), aggregator=ds.sum('inty'),
                          cnorm='log', alpha=10, min_alpha=0
            ).opts(
                active_tools=['box_zoom'],
                tools=['hover'],
                hooks=[new_bounds_hook]
            ).opts(  # weird.. I have no idea why one has to do this. But with one opts you will get an error
                plot=dict(
                    width=800,
                    height=800,
                    xlabel="Retention time (s)",
                    ylabel="mass/charge (Da)"
                )
            )

    hd.dynspread(raster, threshold=0.7, how="add", shape="square")

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