How to add your own plot
This guide shows you how to add a plot to the Image Plots, Line Plots or Probe Plots menu,
computed from the data the GUI has loaded. The example adds a line plot of the number of spikes
along the probe.
How plots are found
Each shank has a plot loader, an instance of
PlotLoader. When the plots are built, the loader
calls every one of its methods whose name starts with image_, scatter_, line_, probe_ or
feature_. Each returns a dict of {menu name: plot data}, where the plot data is an
ImageData, ScatterData, LineData or ProbeData from the same module. A plugin adds a plot by
attaching such a method to each shank’s loader, before the plots are built.
Steps
Create
ibl_alignment_gui/plugins/my_plots.py:from types import MethodType import numpy as np from ibl_alignment_gui.loaders.plot_loader import LineData, skip_missing from ibl_alignment_gui.utils.helpers import shank_loop from iblutil.util import Bunch PLUGIN_NAME = 'My Plots' def setup(controller): """Register the plugin, and the function that adds its plots when data is loaded.""" controller.plugins[PLUGIN_NAME] = Bunch() controller.plugins[PLUGIN_NAME]['activated'] = True controller.plugins[PLUGIN_NAME]['load_data'] = add_plots @shank_loop def add_plots(_, items, **kwargs): """Attach the plot methods to the plot loader of every shank.""" plots = items.model.loaders['plots'] plots.line_spike_count = MethodType(line_spike_count, plots) @skip_missing(['spikes']) def line_spike_count(self): """Line plot of the number of spikes in 20 µm bins along the probe.""" bins = np.arange(self.chn_min, self.chn_max + 20, 20) counts, _ = np.histogram(self.spike_depths, bins) depths = bins[:-1] + 10 line = LineData( x=counts, y=depths, xrange=np.array([0, np.max(counts)]), levels=np.array([0, np.max(counts)]), default_levels=np.array([0, np.max(counts)]), xaxis='Number of spikes', ) return {'Spike count': line}
load_datais called each time a session is loaded, after the shanks are created and before the plots are built.shank_loopcallsadd_plotsonce for every shank and configuration.skip_missing(['spikes'])skips the plot when the session has no spike sorting.Inside the method,
selfis the plot loader.self.dataholds the loaded data, and properties such asself.spike_depthsgive the spikes of the units selected by the current filter, so the plot follows theFilter Plotsmenu.
Register the plugin in
ibl_alignment_gui/plugins/add_plugins.py. Import itssetup, and call it inPlugins.__init__with the other plugins:from ibl_alignment_gui.plugins.my_plots import setup as setup_my_plots class Plugins: def __init__(self, controller): ... setup_my_plots(controller)
Start the GUI and load a session.
Spike countis in theLine Plotsmenu.
For an image or probe plot, return an ImageData or ProbeData and start the method name with
image_ or probe_. The built-in plots in plot_loader.py are worked examples of each.