.. _modulewidgets: Widgets module ============== The :py:mod:`spikeinterface.widgets` module includes plotting function to visualize recordings, sortings, waveforms, and more. Since version 0.95.0, the :py:mod:`spikeinterface.widgets` module supports multiple backends: * | :code:`matplotlib`: static rendering using the `matplotlib `_ package * | :code:`ipywidgets`: interactive rendering within a jupyter notebook using the | `ipywidgets `_ package * | :code:`sortingview`: web-based and interactive rendering using the `sortingview `_ | and `FIGURL `_ packages. Version 0.99.0 also comes with this new backend: * :code:`ephyviewer`: interactive Qt based using the `ephyviewer `_ package Installing backends ------------------- The backends are loaded at run-time and can be installed separately. Alternatively, all dependencies from all backends can be installed with: .. code-block:: bash pip install spikeinterface[widgets] Install matplotlib ^^^^^^^^^^^^^^^^^^ The :code:`matplotlib` backend (default) uses the :code:`matplotlib` package to generate static figures. To install it, run: .. code-block:: bash pip install matplotlib Install ipywidgets ^^^^^^^^^^^^^^^^^^ The :code:`ipywidgets` backend allows users to interact with the plot, for example, by selecting units or scrolling through a time series. To install it, run: .. code-block:: bash pip install matplotlib ipympl ipywidgets To enable interactive widgets in your notebook, add and run a cell with: .. code-block:: python %matplotlib widget .. _sorting_view: Install sortingview ^^^^^^^^^^^^^^^^^^^ The :code:`sortingview` backend generates web-based and shareable links that can be viewed in the browser. To install it, run: .. code-block:: bash pip install sortingview Internally, the processed data to be rendered are uploaded to a public bucket in the cloud, so that they can be visualized via the web (if :code:`generate_url=True`). When running in a Jupyter notebook or JupyterLab, the sortingview widget will also be rendered in the notebook! To set up the backend, you need to authenticate to `kachery-cloud` using your GitHub account by running the following command (you will be prompted with a link): .. code-block:: bash kachery-cloud-init Finally, if you wish to set up another cloud provider, follow the instruction from the `kachery-cloud `_ package ("Using your own storage bucket"). Install ephyviewer ^^^^^^^^^^^^^^^^^^ This backend is Qt based with PyQt5, PyQt6 or PySide6 support. Qt is sometimes tedious to install. For a pip-based installation, run: .. code-block:: bash pip install PySide6 ephyviewer Anaconda users will have a better experience with this: .. code-block:: bash conda install pyqt=5 pip install ephyviewer Usage ----- You can specify which backend to use with the :code:`backend` argument. In addition, each backend comes with specific arguments that can be set when calling the plotting function. A default backend for a SpikeInterface session can be set with the :py:func:`~spikeinterface.widgets.set_default_plotter_backend` function: .. code-block:: python # matplotlib backend set_default_plotter_backend(backend="ipywidgets") print(get_default_plotter_backend()) # >>> "ipywidgets" All :code:`plot_*` functions return a :code:`BackendPlotter` instance. Different backend-specific plotters can expose different attributes. For example, the :code:`matplotlib` plotter has the :code:`figure`, :code:`ax`, and :code:`axes` (for multi-axes plots) attributes to enable further customization. matplotlib ^^^^^^^^^^ The :code:`plot_*(..., backend="matplotlib")` functions come with the following additional (and optional) arguments: * :code:`figure`: Matplotlib figure. When None, it is created. Default None * :code:`ax`: Single matplotlib axis. When None, it is created. Default None * :code:`axes`: Multiple matplotlib axes. When None, they are created. Default None * :code:`ncols`: Number of columns to create in subplots. Default 5 * :code:`figsize`: Size of matplotlib figure. Default None * :code:`figtitle`: The figure title. Default None .. code-block:: python # matplotlib backend w = plot_traces(recording=recording, backend="matplotlib") **Output:** .. image:: ../images/mpl_timeseries.png ipywidgets ^^^^^^^^^^ The :code:`plot_*(..., backend="ipywidgets")` functions are only available in Jupyter notebooks or JupyterLab after calling the :code:`%matplotlib widget` magic line. Each function has the following additional arguments: * :code:`width_cm`: Width of the figure in cm (default 10) * :code:`height_cm`: Height of the figure in cm (default 6) * :code:`display`: If True, widgets are immediately displayed .. code-block:: python from spikeinterface.preprocessing import common_reference # ipywidgets backend also supports multiple "layers" for plot_traces rec_dict = dict(filt=recording, cmr=common_reference(recording)) w = sw.plot_traces(recording=rec_dict, backend="ipywidgets") **Output:** .. image:: ../images/ipy_timeseries.gif sortingview ^^^^^^^^^^^ The :code:`plot_*(..., backend="sortingview")` generate web-based GUIs, which are also shareable with a link (provided that :code:`kachery-cloud` is correctly setup, see :ref:`sorting_view`). The functions have the following additional arguments: * :code:`generate_url`: If True, the figurl URL is generated and printed. Default True * :code:`display`: If True and in jupyter notebook/lab, the widget is displayed in the cell. Default True * :code:`figlabel`: The figurl figure label. Default None * :code:`height`: The height of the sortingview View in jupyter. Default None .. code-block:: python # sortingview backend w_ts = sw.plot_traces(recording=recording, backend="sortingview") w_ss = sw.plot_sorting_summary(sorting_analyzer=sorting_analyzer, curation=True, backend="sortingview") **Output:** * `plot_traces link `_ .. image:: ../images/sv_timeseries.png * `Sorting summary link `_ .. image:: ../images/sv_summary.png The :code:`sortingview` plotter allows one to combine multiple :code:`View`s using the :code:`sortingview` API. For example, here is how to combine the timeseries and sorting summary generated above in multiple tabs: .. code-block:: python import sortingview.views as vv v_ts = w_ts.view v_ss = w_ss.ciew v_summary = vv.TabLayout( items=[ vv.TabLayoutItem( label='Timeseries', view=v_ts ), vv.TabLayoutItem( label='Sorting Summary', view=v_ss ) ] ) # generate URL url = v_summary.url(label="Example multiple tabs") print(url) ephyviewer ^^^^^^^^^^ The :code:`ephyviewer` backend is currently only available for the :py:func:`~spikeinterface.widgets.plot_traces()` function. .. code-block:: python plot_traces(recording=recording, backend="ephyviewer", mode="line", show_channel_ids=True) .. image:: ../images/plot_traces_ephyviewer.png Available plotting functions ---------------------------- * :py:func:`~spikeinterface.widgets.plot_agreement_matrix` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_all_amplitudes_distributions` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_amplitudes` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_autocorrelograms` (backends: :code:`matplotlib`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_confusion_matrix` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_comparison_collision_by_similarity` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_crosscorrelograms` (backends: :code:`matplotlib`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_isi_distribution` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_motion` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_multicomparison_agreement` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_multicomparison_agreement_by_sorter` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_multicomparison_graph` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_peak_activity` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_probe_map` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_quality_metrics` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_rasters` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_sorting_summary` (backends: :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_spike_locations` (backends: :code:`matplotlib`, :code:`ipywidgets`) * :py:func:`~spikeinterface.widgets.plot_spikes_on_traces` (backends: :code:`matplotlib`, :code:`ipywidgets`) * :py:func:`~spikeinterface.widgets.plot_template_metrics` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_template_similarity` (backends: ::code:`matplotlib`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_traces` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`, :code:`ephyviewer`) * :py:func:`~spikeinterface.widgets.plot_unit_depths` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_unit_locations` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_unit_presence` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_unit_probe_map` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_unit_summary` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_unit_templates` (backends: :code:`matplotlib`, :code:`ipywidgets`, :code:`sortingview`) * :py:func:`~spikeinterface.widgets.plot_unit_waveforms_density_map` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_unit_waveforms` (backends: :code:`matplotlib`, :code:`ipywidgets`) * :py:func:`~spikeinterface.widgets.plot_study_run_times` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_study_unit_counts` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_study_agreement_matrix` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_study_summary` (backends: :code:`matplotlib`) * :py:func:`~spikeinterface.widgets.plot_study_comparison_collision_by_similarity` (backends: :code:`matplotlib`)