API Reference
Overview
Interactive data visualization for signals, videos, and complex data objects.
datanavigator provides the modality-agnostic data-navigation primitives
– browsers, asset managers, events. The point-tracking UI, annotation
containers (VideoAnnotation, VideoAnnotations), and
Lucas-Kanade helpers (lucas_kanade, lucas_kanade_rstc) used to
live here too; in 1.5.0 they were relocated to the dustrack
package alongside its DeepLabCut workflow. See dustrack.DUSTrack /
dustrack.VideoAnnotation for the new home. git log --follow
dustrack/annotations.py traces the full pre-relocation history.
Browsers
GenericBrowser: Generic class to browse data. Meant to be extended.
SignalBrowser: Browse an array of pysampled.Data elements, or 2D arrays.
PlotBrowser: Scroll through an array of complex data where a plotting function is defined for each element.
VideoBrowser: Scroll through the frames of a video.
VideoPlotBrowser: Browse through video and 1D signals synced to the video side by side.
ComponentBrowser: Browse signals (e.g., from periodic motion) as scatterplots of components (e.g., from UMAP, PCA).
Video I/O
Assets
Button: Custom button widget with a ‘name’ state.
StateButton: Button widget that stores a number/coordinate state.
ToggleButton: Button widget with a toggle state.
Selector: Select points in a plot using the lasso selection widget.
StateVariable: Manage state variables with multiple states.
EventData: Manage the data from one event type in one trial.
Event: Manage selection of a sequence of events.
Assetcontainers
AssetContainer: Container for managing assets such as buttons, memory slots, etc.
Buttons: Manager for buttons in a matplotlib figure or GUI.
Selectors: Manager for selector objects for picking points on line2D objects.
MemorySlots: Manager for memory slots to store and navigate positions.
StateVariables: Manager for state variables.
Events: Manager for event objects.
-
class datanavigator.GenericBrowser(figure_handle: Figure = None)
Generic class that defines base functionality. Meant to be extended before use.
- Features:
Navigate using arrow keys.
Store positions in memory using number keys (e.g. for flipping between positions when browsing a video).
Quickly add toggle and push buttons.
Design custom functions and assign hotkeys to them (add_key_binding).
- Default Navigation (arrow keys):
ctrl+k - show all keybindings
right - forward one frame
left - back one frame
up - forward 10 frames
down - back 10 frames
shift+left - first frame
shift+right - last frame
shift+up - forward nframes/20 frames
shift+down - back nframes/20 frames
-
update_assets()
Update the display of various assets.
-
update(event=None)
Update the browser. Extended classes are expected to implement their update function.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
update_without_clear(event=None)
Update the browser without clearing the axis.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
add_item_dropdown(names: list[str] | None = None, var_name: str = 'item') → StateVariable
Add a sidebar dropdown to jump straight to a browsed item by name.
Generic across browsers: the dropdown is two-way bound to
_current_idx. Picking an entry moves the browse index and
redraws; arrow-key navigation keeps the dropdown in step (see
_sync_item_dropdown(), invoked from update_assets()).
Built on the StateVariable(widget="dropdown") machinery – a
QComboBox on Qt, read-only text fallback on non-Qt backends.
Suited to browsing tens-to-hundreds of named items (signals, plot
items); not to scrubbing thousands of video frames, which is why
the video browsers leave it off.
Idempotent: re-calling with the same var_name replaces the
existing dropdown (e.g. to relabel once the items are known).
- Parameters:
-
- Returns:
The registered StateVariable.
-
mpl_remove_bindings(key_list: list[str])
Remove existing key bindings in matplotlib.
- Parameters:
key_list (list[str]) – List of keys to remove bindings for.
-
cleanup()
Perform cleanup, for example, when the figure is closed.
-
mpl_restore_bindings()
Restore any modified default keybindings in matplotlib.
-
reset_axes(axis: str = 'both', event=None, axes=None)
Reframe data within matplotlib axes.
- Parameters:
axis (str, optional) – Axis to reset. Defaults to “both”.
event (optional) – Event that triggered the reset. Defaults to None.
axes (Iterable[Axes] | None, optional) – Restrict the walk to
this subset of axes. None (default) walks
self.figure.axes — the historical behaviour.
Cursor-aware dispatch in VideoPointAnnotator._reset_view_all
passes a 2-element list [_ax_trace_x, _ax_trace_y] to
scope the refit to the trace pair when the cursor is over
one of them.
-
add_key_binding(key_name: str, on_press_function: callable, description: str = None, *, group: str | None = None, on_button: bool = False)
Add a key binding to the browser.
- Parameters:
key_name – Key to bind (matplotlib key-event string, e.g. “s”,
“ctrl+a”, “shift+left”).
on_press_function – Function to call when the key is pressed.
description – Human-readable label shown in the cheatsheet.
Defaults to on_press_function.__name__.
group – Section header in the cheatsheet dialog. None
falls into the “Other” section (rendered last).
on_button – When True, find a button whose action_func
is identically on_press_function and append
" ({key_name})" to its label. The match is by is
comparison — pass the same callable object to both
Buttons.add() and this method (no intermediate
lambdas) or the hint won’t attach. Resolution is
symmetric: if the button is added after the binding,
Buttons.add() performs the same scan.
-
remove_key_binding(key_name: str)
Remove a key binding from the browser.
- Parameters:
key_name (str) – Key to remove the binding for.
-
set_default_keybindings()
Set default key bindings for navigation.
-
increment(step: int = 1)
Increment the current index.
- Parameters:
step (int, optional) – Number of steps to increment. Defaults to 1.
-
decrement(step: int = 1)
Decrement the current index.
- Parameters:
step (int, optional) – Number of steps to decrement. Defaults to 1.
-
go_to_start()
Go to the start of the data.
-
go_to_end()
Go to the end of the data.
-
increment_frac(n_steps: int = 20)
Browse the entire dataset in n_steps. Increment the current index by a fraction of the total length.
- Parameters:
n_steps (int, optional) – Number of steps to divide the total length into. Defaults to 20.
-
decrement_frac(n_steps: int = 20)
Decrement the current index by a fraction of the total length.
- Parameters:
n_steps (int, optional) – Number of steps to divide the total length into. Defaults to 20.
-
copy_to_clipboard()
Copy the current figure window to the clipboard.
On a Qt backend, grabs the entire QMainWindow – the
matplotlib canvas plus every Qt-side widget parented to it
(left-column dock with buttons / statevariables, fast_render
image pane, downstream sidebars added by consumers such as
DUSTrack). The pre-rc2 path savefig’d the figure alone and
missed all of them; on a DUSTrack window the clipboard image
would show the trace canvas with nothing where the sidebar /
image pane visually sat.
On non-Qt backends (Agg, headless), falls back to copying just
the matplotlib figure via savefig.
Requires a Qt binding (PyQt5 / PyQt6 / PySide2 / PySide6); imported
lazily via qtpy so installs without Qt still get the rest of
the package. pip install datanavigator[qt] pulls PyQt6.
-
show_key_bindings()
Open the keyboard-shortcut cheatsheet.
On a Qt-backed figure: a modeless QDialog with one section
per KeyBinding.group (insertion order; None group
rendered last as “Other”). Each section is a 2-column table —
monospace shortcut on the left, description on the right.
On non-Qt backends: prints the same content to stdout. The
pre-rc2 TextView overlay is gone; matplotlib doesn’t host a
nice cheatsheet without the Qt path.
-
pan(direction: str = 'left', frac: float = 0.2)
Pan the view.
- Parameters:
direction (str, optional) – Direction to pan. Defaults to “left”.
frac (float, optional) – Fraction of the view to pan. Defaults to 0.2.
-
has(asset_type: str) → bool
Check if the browser has a specific asset type.
- Parameters:
asset_type (str) – Type of asset to check for.
- Returns:
True if the asset type is present, False otherwise.
- Return type:
bool
-
class datanavigator.SignalBrowser(plot_data: list[pysampled.core.Data], titlefunc: Callable | None = None, figure_handle: Figure | None = None, reset_on_change: bool = False, signal_names: list[str] | None = None, show_signal_dropdown: bool = True)
Browse an array of pysampled.Data elements, or 2D arrays.
-
update(event=None)
Update the browser.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
add_signal_dropdown(names: list[str] | None = None, var_name: str = 'signal') → StateVariable
Add the signal-selection dropdown (a thin wrapper).
Delegates to GenericBrowser.add_item_dropdown() with a
"signal" row label. names=None derives labels from each
entry’s name (falling back to "signal <i>" via
_default_item_names()). See add_item_dropdown() for the
full contract: idempotent relabeling, Qt vs text rendering, and the
two-way _current_idx binding.
-
class datanavigator.PlotBrowser(plot_data: list, plot_func: tuple[callable, callable] | callable, figure_handle: plt.Figure = None, item_names: list[str] | None = None, show_item_dropdown: bool = True, **plot_kwargs)
Takes a list of data, and a plotting function (or a pair of setup
and update functions) that parses each of the elements in the array.
Assumes that the plotting function is going to make one figure.
-
get_current_data()
Data getter. Plotting data is a list of objects that are being
plotted one at a time. This function returns the current object.
-
update(event: Any = None)
Update the browser.
-
class datanavigator.VideoBrowser(vid_name: str, titlefunc: ~typing.Callable | None = None, figure_or_ax_handle: ~matplotlib.axes._axes.Axes | ~matplotlib.figure.Figure | None = None, image_process_func: ~typing.Callable = <function VideoBrowser.<lambda>>, fast_render: bool = False)
Scroll through the frames of a video, extract clips of interest.
If figure_handle is an axis handle, the video will be plotted in that axis.
- Future Enhancements:
Extend VideoBrowser to play, pause, and extract clips using hotkeys.
Show timeline in VideoBrowser.
Add clickable navigation.
-
increment_frac(n_steps: int = 100) → None
Browse entire dataset in n_steps.
- Parameters:
n_steps (int) – Number of steps to increment.
-
decrement_frac(n_steps: int = 100) → None
Browse entire dataset in n_steps.
- Parameters:
n_steps (int) – Number of steps to decrement.
-
update() → None
Update the video frame.
Extract a clip from the video.
- Parameters:
start_frame (Optional[int]) – Starting frame of the clip.
end_frame (Optional[int]) – Ending frame of the clip.
fname_out (Optional[str]) – Output filename.
out_rate (Optional[int]) – Output frame rate.
- Returns:
Path to the extracted clip.
- Return type:
str
-
class datanavigator.VideoPlotBrowser(vid_name: str, signals: Dict[str, Data], titlefunc: Callable | None = None, figure_handle: Figure | None = None, event_win: tuple | None = None)
Browse a video and an array of pysampled.Data side by side.
- Parameters:
vid_name (str) – Path to the video file.
signals (Dict[str, pysampled.Data]) – Dictionary of signals.
titlefunc (Optional[Callable]) – Function to generate the title for the plot.
figure_handle (Optional[plt.Figure]) – Handle to the figure.
event_win (Optional[tuple]) – Event window. Visualize signals around an event. Use this to create “scrolling” plot visualizations, e.g. [-0.5, 1.].
-
update() → None
Update the video frame and signals.
-
onclick(event) → None
Right click mouse to seek to that frame.
- Parameters:
event – Matplotlib event.
Save a video of screengrabs.
- Parameters:
start_frame (Optional[int]) – Starting frame of the clip. Defaults to the first memory slot.
end_frame (Optional[int]) – Ending frame of the clip. Defaults to the second memory slot.
sav_dir (Optional[str]) – Directory to save the clip. If not provided, a timestamped directory is created.
- Returns:
Path to the saved video file.
-
class datanavigator.ComponentBrowser(data: ndarray, data_transform: ndarray, labels: ndarray | None = None, figure_handle: Figure | None = None, class_names: dict[int, str] | None = None, desired_class_names: dict[int, str] | None = None, annotation_names: dict[int, str] | None = None)
-
property n_signals: int
Return the number of signals.
-
property n_timepts: int
Return the number of time points.
-
property colors: list[tuple]
Return the colors for each class.
-
property signal: Data
Return the 2D Numpy array as a signal.
-
select_signal_piece_dblclick(event: Any) → None
Double click a signal piece in the timecourse view to highlight that point.
- Parameters:
event (Any) – The mouse event.
-
onpick(event: Any) → None
Single click a projected point.
- Parameters:
event (Any) – The pick event.
-
update() → None
Update the plot with the current data index.
-
update_class_info_text(draw: bool = True) → None
Update the class info text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_desired_class_info_text(draw: bool = True) → None
Update the desired class info text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_mode_text(draw: bool = True) → None
Update the mode text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_message_text(text: str, draw: bool = True) → None
Update the message text.
- Parameters:
-
-
toggle_mode(event: Any | None = None) → None
Toggle between correction and annotation modes.
- Parameters:
event (Any | None) – The key event.
-
update_colors(data_idx: list[int] | None = None, draw: bool = True) → None
Update the colors of the plot.
- Parameters:
-
-
update_all() → None
Update all components of the plot.
-
clear_axes(event: Any | None = None) → None
Clear the axes.
- Parameters:
event (Any | None) – The key event.
-
classlabels_to_dict() → dict[int, dict[str, int | str | list[str]]]
Convert class labels to a dictionary.
- Returns:
Dictionary of class labels.
- Return type:
dict[int, dict[str, int | str | list[str]]]
-
set_classlabels(classlabels_dict: dict[int, dict[str, int | str | list[str]]]) → None
Set class labels from a dictionary.
- Parameters:
classlabels_dict (dict[int, dict[str, int | str | list[str]]]) – Dictionary of class labels.
-
class datanavigator.Video(uri: str, ctx=cpu(0), width: int = -1, height: int = -1, num_threads: int = 0, fault_tol: int = -1)
Extended VideoReader class with additional methods.
-
gray(frame_num: int) → ndarray
Convert a frame to grayscale.
- Parameters:
frame_num (int) – Frame number to convert.
- Returns:
Grayscale frame.
- Return type:
np.ndarray
-
class datanavigator.VideoReader(uri, ctx=None, width: int = -1, height: int = -1, num_threads: int = 0, fault_tol: int = -1, pix_fmt: str | None = None)
decord-compatible random-access video reader backed by PyAV+TOC.
The constructor signature mirrors decord.VideoReader so existing
call sites and subclasses continue to work; ctx, width,
height, num_threads, fault_tol are accepted but ignored
(PyAV honors the source resolution and is CPU-only here).
A frame-index TOC and per-frame pts/duration table are built from
the video at open time and cached next to it as
<video>.dnav-toc (JSON content; the .json extension is
intentionally omitted so *.json walkers in downstream tooling
don’t pick the sidecar up). The key is path + size + mtime +
head/tail SHA-256. On a cache hit the second open is sub-second;
on a miss the first open prints a one-line “building TOC…” notice.
Use precompute_toc() to warm the cache for a set of videos
before an interactive session.
-
get_frame_timestamp(indices) → ndarray
Return (N, 2) array of [start, end] times in seconds
for each requested frame — decord-compatible.
On a v2 cache hit this is a slice; on a v1 cache hit (legacy
sidecar) or never-cached file, the per-frame pts/duration table
is built from a full demux+decode pass on first call (announced
with a one-line notice) and the sidecar is upgraded in place
if writable.
-
datanavigator.cpu(device_id: int = 0) → _CpuCtx
decord.cpu() compatibility shim. Returns a sentinel; PyAV is CPU-only.
-
datanavigator.precompute_toc(paths: Iterable[str | PathLike], *, force: bool = False, show_progress: bool = True, progress_callback: Callable[[int, int, str, str], None] | None = None, cancel_check: Callable[[], bool] | None = None) → dict
Batch-build and cache TOCs + per-frame timestamps for a sequence of
video files.
Useful before an annotation session, so the per-video “Building
TOC…” pause doesn’t happen interactively:
import glob, datanavigator
datanavigator.precompute_toc(glob.glob("data/*.mp4"))
For folder-walking semantics, see precompute_toc_folder().
- Parameters:
paths – Iterable of video file paths.
force – If True, rebuild + overwrite even when a valid cache exists.
(A valid v1 sidecar counts as a hit; pass force=True to
upgrade pre-1.3 sidecars to schema v2 with per-frame
timestamps.)
show_progress – If True (default), wrap iteration in a tqdm bar.
Suppressed when progress_callback is set, so UI callers
don’t get both a bar and their own per-file updates.
progress_callback – Optional fn(idx, total, path, status)
invoked after each video is resolved (hit / built / error).
idx is the zero-based position in the input list,
total is the full length, path is the string path
passed in, status is the same per-file string written
into the return dict. Lets UI consumers drive their own
progress widget without parsing tqdm output.
cancel_check – Optional zero-arg callable polled at the top of
each video. If it returns truthy, the loop exits early and
the partial {path: status} dict is returned (already-
processed entries kept). Used by UI consumers’ Cancel
button.
- Returns:
{path: status} where status is "hit" (cache already valid),
"built" (rebuilt and cached), "built (uncached)" (built
but sidecar save failed), or f"error: {msg}" (skipped).
-
datanavigator.precompute_toc_folder(folder: str | PathLike | Iterable[str | PathLike], *, extensions: Iterable[str] = ('.mp4', '.mov', '.mkv', '.avi', '.m4v'), recursive: bool = True, force: bool = False, show_progress: bool = True, progress_callback: Callable[[int, int, str, str], None] | None = None, cancel_check: Callable[[], bool] | None = None) → dict
Walk a folder (or list of folders / files) and build TOCs for each video.
Thin sibling of precompute_toc() that handles directory walking
so callers don’t have to glob themselves. Each folder entry may
be a directory (walked for extensions) or a file (kept as-is).
Non-existent entries that were named explicitly are surfaced as
"error: missing" in the returned dict; directories that turn up
no matching videos are silently empty.
Example:
import datanavigator
results = datanavigator.precompute_toc_folder(
"M:/us_videos_for_tracking2",
)
# {'M:/.../foo.mp4': 'hit', 'M:/.../bar.mp4': 'built', ...}
- Parameters:
folder – A directory path, a file path, or an iterable mixing both.
extensions – File extensions to include (case-insensitive). Default
covers the common video container formats.
recursive – If True (default), recurse into subdirectories.
force – Forwarded to precompute_toc() — rebuild even on hit.
show_progress – Forwarded to precompute_toc() — tqdm bar.
progress_callback – Forwarded to precompute_toc().
cancel_check – Forwarded to precompute_toc().
- Returns:
{path: status} per precompute_toc(), with an extra
"error: missing" entry for any explicitly-named path that
doesn’t exist.
-
class datanavigator.Button(ax, name: str, **kwargs)
Add a ‘name’ state to a matplotlib widget button.
-
class datanavigator.StateButton(ax, name: str, start_state: Any, **kwargs)
Store a number/coordinate in a button.
-
class datanavigator.ToggleButton(ax, name: str, start_state: bool = True, **kwargs)
Add a toggle button to a matplotlib figure.
For example usage, see PlotBrowser.
-
set_text() → None
Set the text of the toggle button.
-
toggle(event=None) → None
Toggle the state of the button.
-
set_state(state: bool) → None
Set the state of the button.
-
class datanavigator.Selector(plot_handle: Line2D)
Select points in a plot using the lasso selection widget.
Indices of selected points are stored in self.sel.
Example
f, ax = plt.subplots(1, 1)
ph, = ax.plot(np.random.rand(20))
plt.show(block=False)
ls = gui.Lasso(ph)
ls.start()
– play around with selecting points –
ls.stop() -> disconnects the events
-
get_data() → ndarray
Get the data points of the plot.
-
onselect(verts: List[tuple]) → None
Select if not previously selected; Unselect if previously selected.
-
start(event=None) → None
Start the lasso selection.
-
stop(event=None) → None
Stop the lasso selection.
-
toggle(event=None) → None
Toggle the lasso selection.
-
class datanavigator.StateVariable(name: str, states: list, widget: str = 'label')
Manage state variables with multiple states.
The widget hint is metadata read by the rc2 Qt sidebar to choose
a control surface for this state variable: "label" (read-only
text line; default), "dropdown" (QComboBox), or "toggle"
(mutually-exclusive row of checkable QToolButtons). On non-Qt
backends the hint is ignored and the value renders as plain text
via the legacy TextView path.
-
property current_state: Any
Get the current state.
-
n_states() → int
Get the number of states.
-
add_on_change(callback: Callable[[], None]) → None
Register a no-arg callback fired after state mutations.
Fires on every set_state() / cycle() /
cycle_back() call, regardless of whether the index
actually changed – consumers that need a real-change guard
should track the previous value themselves (e.g.
VideoPointAnnotator._on_active_label_change()).
-
cycle() → None
Cycle to the next state.
-
cycle_back() → None
Cycle to the previous state.
-
set_state(state: int | str) → None
Set the state.
-
class datanavigator.AssetContainer(parent: Any)
Container for assets such as a button, memoryslot, etc.
- Parameters:
parent (Any) – matplotlib figure, or something that has a ‘figure’ attribute that is a figure.
-
__getitem__(key: int | str) → Any
Return an asset by the name key or by position in the list.
-
add(asset: Any) → Any
Add an asset to the container.
-
remove(name: str) → Any
Remove and return the asset with this name.
Counterpart to add(); raises KeyError if no asset in
the container carries that name. The caller is responsible for
tearing down any plot handles / Qt widgets the asset owns –
AssetContainer only manages the membership list.
-
class datanavigator.Buttons(parent: Any)
Manager for buttons in a matplotlib figure or GUI (see GenericBrowser for example).
Phase 3 of the 1.4.0 Qt refactor (soft mode): when the parent’s figure
is on a Qt canvas AND no explicit pos is given, add() builds a
native QPushButton in a QVBoxLayout column hosted by a QDockWidget on
the QMainWindow’s LeftDockWidgetArea (pre-rc2: QToolBar; see
_qt._get_buttons_widget()). On every other backend, or when
an explicit pos is given, the original matplotlib-widgets path
runs unchanged. The returned object exposes the same public surface
either way (name, on_clicked, plus toggle-specific state
/ toggle / set_text / set_state).
Lifecycle gotcha: Buttons.add() reads the figure’s canvas at call
time. If a Figure subclass adds buttons inside its own __init__
(as in datanavigator.examples.ButtonDemo), this runs before
matplotlib attaches a Qt canvas to the figure, so those buttons end
up on the mpl path even under QtAgg. The buttons still function;
they just miss the Phase 3 perf win. Browsers that take a
figure_handle (the common case) are unaffected, because the figure
is fully constructed before any button is added.
rc2 row-cursor note: _mpl_row_cursor tracks the next vertical
slot for the mpl-fallback layout independent of len(self).
add() and add_separator() used to derive y from len(self),
which assumed one button per row. add_multi() (one row, N
buttons) breaks that assumption, so the cursor is bumped by 1 per
row (regardless of how many buttons land on it) while len(self)
still grows by N. For single-add-only flows the two stay equal,
preserving pre-rc2 placement.
-
add(text: str = 'Button', action_func: Callable | List[Callable] | None = None, pos: tuple | None = None, w: float = 0.25, h: float = 0.05, buf: float = 0.01, type_: str = 'Push', style_tag: str | None = None, **kwargs) → Button
Add a button to the parent figure / object.
If pos is provided, then w, h, and buf will be ignored.
-
register_style(name: str, styler: Callable[[Any], None]) → None
Register a per-button styler under name.
Consumers call this once at setup, then pass style_tag=name
to add() / add_multi(). Re-registering an existing
name (including a styles built-in) replaces the binding
– consumer registrations always win over built-ins.
styler is invoked with the freshly-constructed button as its
sole argument at the tail of _finalize_button(). It should
detect the Qt path via getattr(b, "_qt_btn", None) and apply
QSS / palette manipulation; mpl-path styling is the styler’s
choice (the dnav built-ins no-op there).
-
reapply_styles() → None
Re-run the styler for every already-added button.
Useful after register_style() changes a binding (e.g. a
theme swap re-registers "primary" with a dark-mode palette
and the existing buttons need to repaint).
-
add_multi(*specs: dict) → List[Any]
Add N buttons side-by-side in a single row.
Each spec is a dict of kwargs accepted by add() –
typically {text=..., action_func=..., type_=...}. Returns the
list of created button objects in spec order.
On the Qt path, all N buttons are children of a single QWidget
with a QHBoxLayout inserted into the buttons column’s
QVBoxLayout; the row therefore consumes one vertical slot in the
sidebar regardless of N. On the mpl fallback path, the row’s
width is divided evenly across N buttons at a shared y, and
_mpl_row_cursor is bumped by 1 (not N) so a following
add() lands on the next row, not N rows down.
Edge cases:
- add_multi() with no specs is a no-op and returns [].
- add_multi(one_spec) is equivalent to add(**one_spec) –
full-width single button – and returns a one-element list.
-
add_separator(name: str | None = None, style: str = 'single') → None
Add a visual group boundary between buttons.
On the Qt path (figure on a Qt canvas), inserts a sunken
QFrame.HLine into the buttons-column QVBoxLayout – a
thin line marking a group boundary. style="double" inserts
two stacked HLines for a stronger section break, used by
DUSTrack to mark major button groups in its rc2 sidebar. On
the mpl path, inserts one (or two, for style="double")
invisible buttons that occupy layout slots so subsequent
buttons are pushed down. (Pre-rc2 the Qt-path inserted a
QToolBar.addSeparator() QAction; single-HLine only.)
Promoted to a first-class API for downstream consumers (DUSTrack)
that previously hand-rolled invisible spacers by mutating
matplotlib.widgets.Button internals (.ax, .label,
.ax.patch) – internals that don’t exist on the Qt path.
- Parameters:
-
-
class datanavigator.Selectors(parent: Any)
Manager for selector objects - for picking points on line2D objects.
-
add(plot_handle: Line2D) → Selector
Add a selector to the container.
-
class datanavigator.MemorySlots(parent: Any)
Manager for memory slots to store and navigate positions.
-
static initialize() → dict
Initialize memory slots.
-
disable() → None
Disable memory slots.
-
enable() → None
Enable memory slots.
-
show(pos: str = 'bottom left') → None
Show memory slot text.
-
update(key: str) → None
Handle memory slot updates.
Initiate when None, go to the slot if it exists, free slot if pressed when it exists.
key is the event.key triggered by a callback.
-
update_display() → None
Refresh memory slot text if it is not hidden.
-
hide() → None
Hide the memory slot text.
-
is_enabled() → bool
Check if memory slots are enabled.
-
class datanavigator.StateVariables(parent: Any)
Manager for state variables.
-
asdict() → dict
Return state variables as a dictionary.
-
add(name: str, states: list, widget: str = 'label') → StateVariable
Add a state variable to the container.
- Parameters:
name – identifier; must be unique within the container.
states – the rotation of values this variable can take.
widget – rc2 Qt-sidebar control surface hint – one of
"label" (read-only text; default; matches pre-rc2
behavior), "dropdown" (QComboBox), or "toggle"
(mutually-exclusive QToolButton row). Ignored on non-Qt
backends.
-
show(pos: str = 'bottom right', fax=None) → None
Show state variables.
rc2: tries the interactive Qt widget first (dropdowns / toggles
/ labels per each StateVariable’s widget hint),
mounted in the QDockWidget column beneath the buttons. Falls
back to the pre-rc2 utils.TextView path on non-Qt
backends or if no Qt window is found. The pos / fax
arguments are only consulted on the TextView fallback; on the
Qt path they’re ignored (the widget’s position is dock-managed).
-
update_display(draw: bool = True) → None
Update the display of state variables.
-
class datanavigator.Events(parent: Any)
Manager for Event objects.
-
add(name: str, size: int, fname: str, data_id_func: ~typing.Callable, color: str | int, pick_action: str = 'overwrite', ax_list: list | None = None, win_remove: tuple[float, float] = (-0.1, 0.1), win_add: tuple[float, float] = (-0.25, 0.25), add_key: str | None = None, remove_key: str | None = None, save_key: str | None = None, show: bool = True, data_func: ~typing.Callable = <class 'float'>, **plot_kwargs) → Event
Add an event.
- Parameters:
name (str) – Name of the event.
size (int) – Length of the sequence. For example, if this is 2, then the event is a pair of start and end times.
fname (str) – File name to save the event.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
color (str | int) – Color used to display the event
pick_action (str, optional) – Action to take when picking an event (‘overwrite’ or ‘append’). Use overwrite if there can only be one sequence per ‘signal’. If there can be multiple, use ‘append’. Defaults to overwrite. Defaults to ‘overwrite’.
ax_list (list | None, optional) – list of axes on which to show the event. Defaults to None.
win_remove (tuple[float, float], optional) – Window relative to the mouse position to search for removing an event. Defaults to (-0.1, 0.1).
win_add (tuple[float, float], optional) – Window relative to the mouse position to search for adding an event. Defaults to (-0.25, 0.25). For future use.
add_key (str | None, optional) – Keyboard shortcut for adding the event. Defaults to None.
remove_key (str | None, optional) – Keyboard shortcut for removing the event. Defaults to None.
save_key (str | None, optional) – Keyboard shortcut for saving the events to a JSON file. Defaults to None.
show (bool, optional) – Event visibility. Defaults to True.
data_func (Callable, optional) – Function to apply on the incoming event. Intended use is for type casting. Defaults to float.
- Returns:
_description_
- Return type:
Event
-
add_from_file(fname: str, data_id_func: ~typing.Callable, ax_list: list | None = None, add_key: str | None = None, remove_key: str | None = None, save_key: str | None = None, show: bool = True, data_func: ~typing.Callable = <class 'float'>, **plot_kwargs) → Event
Add events from an existing file.
Intended use case - events are created by another algorithm meant to be edited using a browser in the datanavigator.
- Parameters:
fname (str) – File name to load the events.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
ax_list (list | None, optional) – list of axes on which to show the event. Defaults to None.
add_key (str | None, optional) – Keyboard shortcut for adding the event. Defaults to None.
remove_key (str | None, optional) – Keyboard shortcut for removing the event. Defaults to None.
save_key (str | None, optional) – Keyboard shortcut for saving the events to a JSON file. Defaults to None.
show (bool, optional) – Event visibility. Defaults to True.
data_func (Callable, optional) – Function to apply on the incoming event. Intended use is for type casting. Defaults to float.
- Returns:
The created Event object.
- Return type:
Event
-
setup_display() → None
Setup display for all events.
-
update_display(draw: bool = True) → None
Update display for all events
-
class datanavigator.Event(name: str, size: int, fname: str, data_id_func: ~typing.Callable | None = <function Event.<lambda>>, color: str | int = 'random', pick_action: str = 'overwrite', ax_list: list | None = None, win_remove: tuple[float, float] = (-0.1, 0.1), win_add: tuple[float, float] = (-0.25, 0.25), data_func: ~typing.Callable = <class 'float'>, **plot_kwargs)
Manage selection of a sequence of events (of length >= 1).
- Variables:
name (str) – Name of the event.
size (int) – Length of the sequence.
fname (str) – File name to load and save events.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
color (str) – Color of the event. Defaults to a random color.
pick_action (str) – Action to take when picking an event (‘overwrite’ or ‘append’). Use overwrite if there can only be one sequence per ‘signal’. If there can be multiple, use ‘append’. Defaults to overwrite
ax_list (list) – list of axes on which to show the event.
win_remove (tuple) – Window relative to the mouse position to search for removing an event. Defaults to (-0.1, 0.1).
win_add (tuple) – Window relative to the mouse position to search for adding an event. Defaults to (-0.25, 0.25).
data_func (Callable) – Function to process the data.
plot_kwargs (dict) – Keyword arguments for plotting. Commonly used keys are ‘display_type’ (line or fill) and ‘alpha’ to set the transparency level.
-
classmethod from_file(fname: str, **kwargs) → Event
Create an empty events file with the given file name (fname) and any parameters.
Assigns best-guess defaults.
-
classmethod from_data(data: dict, name: str = 'Event', fname: str = '', overwrite: bool = False, **kwargs) → Event
Create an event file by filling in the ‘default’ events extracted by an algorithm.
- Parameters:
data (dict) – Data to create the event file.
name (str) – Name of the event.
fname (str) – File name to save the event.
overwrite (bool) – Whether to overwrite the existing file.
**kwargs – Additional keyword arguments.
tags, algorithm_name, and params will be passed to EventData.
All other keyword arguments will be passed to Event.
- Returns:
The created Event object.
- Return type:
Event
-
all_keys_are_tuples() → bool
Check if all keys are tuples.
Get the header information of the event.
-
load() → tuple[dict, dict]
Load the event data from the file.
-
save() → None
Save the event data to the file.
-
add(event: Any) → None
Pick the time points of an interval and associate it with a supplied ID.
If the first selection is outside the axis, then select the first available time point.
If the last selection is outside the axis, then select the last available time point.
If the selections are not monotonically increasing, then empty the buffer.
If any of the ‘middle’ picks (i.e. not first or last in the sequence) are outside the axes, then empty the buffer.
The parent UI would invoke this method.
- Parameters:
event (Any) – The event to add.
-
remove(event: Any) → None
Remove an event.
- Parameters:
event (Any) – The event to remove.
-
get_current_event_times() → list
Get the current event times.
-
setup_display() → None
Setup event display on one or more axes.
-
update_display(draw: bool = True) → None
Update the event display.
-
to_dict() → dict
Convert the event data to a dictionary.
-
to_portions() → dict
Convert the event data to portions.
-
class datanavigator.EventData(default: list | None = None, added: list | None = None, removed: list | None = None, tags: list | None = None, algorithm_name: str = '', params: dict | None = None)
Manage the data from one event type in one trial.
- Variables:
default (list) – Default events created by an algorithm.
added (list) – Manually added events. Note that if an ‘added’ point is removed, then it will simply be deleted. There will be no record of it.
removed (list) – Events removed from the default list.
tags (list) – Tags associated with the events.
algorithm_name (str) – Name of the algorithm used to generate the default list.
params (dict) – Parameters used to generate the default list.
-
asdict() → dict
Convert the event data to a dictionary.
-
get_size() → int
Return the size of the envent, for example, 2 for start and stop events.
-
get_times() → list
Get the times of all events.
-
to_portions() → _PNInterval
Convert the event times to portions.
-
overlap_duration(other: 'portion.Interval' | tuple) → float
Calculate the duration of overlap with another interval.
-
class datanavigator.TextView(text: List[str] | dict, fax: None | Figure | Axes = None, pos: str | Tuple[float, float, str, str] = 'bottom left')
Show text array line by line.
Phase 2 of the 1.4.0 Qt refactor (soft mode): when fax resolves to
a figure whose canvas is a matplotlib Qt canvas, the text renders as a
native QLabel overlay parented to the canvas (self._overlay set,
self._text stays None). On every other backend the original
Axes.text path runs unchanged (self._overlay is None,
self._text is the mpl Text artist).
The public surface (__init__ signature, .text, .update)
is identical across both paths.
-
parse_text(text: List[str] | dict) → List[str]
Parse text input into a list of strings.
- Parameters:
text (Union[List[str], dict]) – Text input.
- Returns:
Parsed text.
- Return type:
List[str]
-
setup() → None
Setup for showing the text.
-
update(new_text: List[str] | dict = None) → None
Update the text view with new text.
- Parameters:
new_text (Union[List[str], dict], optional) – New text to display. Defaults to None.
-
datanavigator.get_palette(palette_name: str = 'Set2', n_colors: int = 10) → List[Tuple[float, float, float]]
Get a color palette, with fallback if seaborn is not available.
- Parameters:
palette_name (str, optional) – Name of the palette. Defaults to “Set2”.
n_colors (int, optional) – Number of colors. Defaults to 10.
- Returns:
List of RGB tuples.
- Return type:
List[Tuple[float, float, float]]
-
datanavigator.is_path_exists_or_creatable(pathname: str) → bool
True if the passed pathname is a valid pathname for the current OS _and_
either currently exists or is hypothetically creatable; False otherwise.
This function is guaranteed to _never_ raise exceptions.
-
datanavigator.ticks_from_times(times: List[float], tick_lim: Tuple[float, float]) → Tuple[List[float], List[float]]
Generate x, y arrays to supply to plt.plot function to plot a set of x-values (times) as ticks.
- Parameters:
times (List[float]) – List of time values.
tick_lim (Tuple[float, float]) – Limits for the y-axis ticks.
- Returns:
x and y arrays for plotting ticks.
- Return type:
Tuple[List[float], List[float]]
-
datanavigator.get_example_video(dest_folder: str = None, source_url: str = None) → str
Download a sample video file if it doesn’t exist locally and return its path.
Uses a default destination folder and source URL if none are provided.
The default destination is retrieved from _config.get_clip_folder().
The default source URL points to a small jellyfish video.
- Parameters:
dest_folder (str, optional) – The folder where the video should be saved.
Defaults to the folder specified in the configuration.
source_url (str, optional) – The URL from which to download the video.
Defaults to a known test video URL.
- Returns:
The local file path to the downloaded (or existing) video.
- Return type:
str
- Raises:
AssertionError – If a dest_folder is provided but does not exist.
urllib.error.URLError – If the video download fails (e.g., network issue, invalid URL).
-
class datanavigator.EventPickerDemo
Demonstrates browsing signals and picking events using the SignalBrowser.
This class extends SignalBrowser to showcase how to:
- Load multiple signals (random noise in this case).
- Define and manage different types of events (‘pick1’, ‘pick2’, ‘pick3’)
with varying sizes and picking behaviors (‘append’, ‘overwrite’).
Assign keyboard shortcuts for adding, removing, and saving events.
Customize event display (line vs. fill).
Override the update method to ensure event displays are refreshed.
- Key Bindings:
‘1’: Add a ‘pick1’ event (size 1, append).
‘alt+1’: Remove the nearest ‘pick1’ event.
‘ctrl+1’: Save ‘pick1’ events to file.
‘2’: Add a ‘pick2’ event (size 2, append, fill display).
‘alt+2’: Remove the nearest ‘pick2’ event.
‘ctrl+2’: Save ‘pick2’ events to file.
‘3’: Add a ‘pick3’ event (size 3, overwrite).
‘alt+3’: Remove the nearest ‘pick3’ event.
‘ctrl+3’: Save ‘pick3’ events to file.
-
update(event: Any | None = None) → None
The update method is often one that needs to be specified when extending a class.
-
class datanavigator.ButtonDemo(*args: Any, **kwargs: Any)
Demonstrates creating and using custom buttons within a Matplotlib figure.
This class creates a figure and adds two buttons using the datanavigator.core.Buttons manager:
- A ‘Toggle’ button.
- A ‘Push’ button that triggers a callback function (test_callback) when clicked.
-
test_callback(event: Any | None = None) → None
Callback function executed when the ‘push button’ is clicked.
Prints the triggering mouse event to the console.
- Parameters:
event (Optional[Any], optional) – The matplotlib event object associated
with the button click. Defaults to None.
-
set(*, agg_filter=<UNSET>, alpha=<UNSET>, animated=<UNSET>, canvas=<UNSET>, clip_box=<UNSET>, clip_on=<UNSET>, clip_path=<UNSET>, constrained_layout=<UNSET>, constrained_layout_pads=<UNSET>, dpi=<UNSET>, edgecolor=<UNSET>, facecolor=<UNSET>, figheight=<UNSET>, figwidth=<UNSET>, frameon=<UNSET>, gid=<UNSET>, in_layout=<UNSET>, label=<UNSET>, layout_engine=<UNSET>, linewidth=<UNSET>, mouseover=<UNSET>, path_effects=<UNSET>, picker=<UNSET>, rasterized=<UNSET>, size_inches=<UNSET>, sketch_params=<UNSET>, snap=<UNSET>, tight_layout=<UNSET>, transform=<UNSET>, url=<UNSET>, visible=<UNSET>, zorder=<UNSET>)
Set multiple properties at once.
Supported properties are
- Properties:
agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array and two offsets from the bottom left corner of the image
alpha: float or None
animated: bool
canvas: FigureCanvas
clip_box: ~matplotlib.transforms.BboxBase or None
clip_on: bool
clip_path: Patch or (Path, Transform) or None
constrained_layout: unknown
constrained_layout_pads: unknown
dpi: float
edgecolor: :mpltype:`color`
facecolor: :mpltype:`color`
figheight: float
figure: unknown
figwidth: float
frameon: bool
gid: str
in_layout: bool
label: object
layout_engine: {‘constrained’, ‘compressed’, ‘tight’, ‘none’, .LayoutEngine, None}
linewidth: number
mouseover: bool
path_effects: list of .AbstractPathEffect
picker: None or bool or float or callable
rasterized: bool
size_inches: (float, float) or float
sketch_params: (scale: float, length: float, randomness: float)
snap: bool or None
tight_layout: unknown
transform: ~matplotlib.transforms.Transform
url: str
visible: bool
zorder: float
-
class datanavigator.SelectorDemo
Demonstrates using the Matplotlib LassoSelector widget to select data points.
Creates a scatter plot and adds buttons to start and stop the lasso selection mode.
Selected points are highlighted, and selections can be toggled (selecting an already
selected point unselects it).
-
get_points() → ndarray
Returns the data points currently plotted on the axes.
Used by the LassoSelector to determine which points are inside the lasso path.
- Returns:
A 2D array where each row is (t, x) coordinate of a point.
- Return type:
np.ndarray
-
onselect(verts: list) → None
Callback function executed when a lasso selection is completed.
Determines which points fall within the lasso path defined by verts.
Updates the set of selected indices (self.ind), toggling the selection
state for points within the lasso. Refreshes the plot to show the
currently selected points.
- Parameters:
verts (list) – A list of (x, y) tuples defining the vertices of the
lasso path in display coordinates.
-
start(event: Any | None = None) → None
Activates the LassoSelector widget.
Connected as the callback for the ‘Start selection’ button.
- Parameters:
event (Optional[Any], optional) – The event triggering the start. Defaults to None.
-
stop(event: Any | None = None) → None
Deactivates the LassoSelector widget.
Connected as the callback for the ‘Stop selection’ button.
- Parameters:
event (Optional[Any], optional) – The event triggering the stop. Defaults to None.
-
datanavigator.get_cache_folder() → str
Get the current path of the cache folder.
-
datanavigator.get_clip_folder() → str
Get the current path of the clip folder.
-
datanavigator.set_cache_folder(folder: str) → None
Set the path for the cache folder.
-
datanavigator.set_clip_folder(folder: str) → None
Set the path for storing video clips.
The default on Windows is C:\data\_clipcollection; on
macOS / Linux it is ~/datanavigator/_clipcollection. Either
can be overridden via the CLIP_FOLDER environment variable at
import time, or via this setter at runtime.
Browsers
This module defines the core class called GenericBrowser. It
defines basic functionalities for browsing data, such as navigating
using arrow keys, storing positions in memory (e.g. video frame
numbers), adding buttons, and assigning hotkeys to custom functions.
This class can be extended to create interactive browsers for various
types of data, including plots, signals, and videos.
-
class datanavigator.core.KeyBinding(callback: Callable, description: str, group: str | None = None, on_button: bool = False)
One entry in GenericBrowser._keypressdict.
group drives the section header in
GenericBrowser.show_key_bindings() (None falls into the
“Other” section, rendered last). on_button opts the binding into
button-face hint rendering: the cheatsheet dialog and a matching
button get the shortcut shown alongside the action.
Pre-rc2 this slot was a (callback, description) tuple; the
dataclass is a hard cut — no tuple-style backward compat. Downstream
callers that poke _keypressdict directly (rare) need to migrate
to attribute access.
-
callback: Callable
-
description: str
-
group: str | None = None
-
on_button: bool = False
-
class datanavigator.core.GenericBrowser(figure_handle: Figure = None)
Generic class that defines base functionality. Meant to be extended before use.
- Features:
Navigate using arrow keys.
Store positions in memory using number keys (e.g. for flipping between positions when browsing a video).
Quickly add toggle and push buttons.
Design custom functions and assign hotkeys to them (add_key_binding).
- Default Navigation (arrow keys):
ctrl+k - show all keybindings
right - forward one frame
left - back one frame
up - forward 10 frames
down - back 10 frames
shift+left - first frame
shift+right - last frame
shift+up - forward nframes/20 frames
shift+down - back nframes/20 frames
-
update_assets()
Update the display of various assets.
-
update(event=None)
Update the browser. Extended classes are expected to implement their update function.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
update_without_clear(event=None)
Update the browser without clearing the axis.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
add_item_dropdown(names: list[str] | None = None, var_name: str = 'item') → StateVariable
Add a sidebar dropdown to jump straight to a browsed item by name.
Generic across browsers: the dropdown is two-way bound to
_current_idx. Picking an entry moves the browse index and
redraws; arrow-key navigation keeps the dropdown in step (see
_sync_item_dropdown(), invoked from update_assets()).
Built on the StateVariable(widget="dropdown") machinery – a
QComboBox on Qt, read-only text fallback on non-Qt backends.
Suited to browsing tens-to-hundreds of named items (signals, plot
items); not to scrubbing thousands of video frames, which is why
the video browsers leave it off.
Idempotent: re-calling with the same var_name replaces the
existing dropdown (e.g. to relabel once the items are known).
- Parameters:
-
- Returns:
The registered StateVariable.
-
mpl_remove_bindings(key_list: list[str])
Remove existing key bindings in matplotlib.
- Parameters:
key_list (list[str]) – List of keys to remove bindings for.
-
cleanup()
Perform cleanup, for example, when the figure is closed.
-
mpl_restore_bindings()
Restore any modified default keybindings in matplotlib.
-
reset_axes(axis: str = 'both', event=None, axes=None)
Reframe data within matplotlib axes.
- Parameters:
axis (str, optional) – Axis to reset. Defaults to “both”.
event (optional) – Event that triggered the reset. Defaults to None.
axes (Iterable[Axes] | None, optional) – Restrict the walk to
this subset of axes. None (default) walks
self.figure.axes — the historical behaviour.
Cursor-aware dispatch in VideoPointAnnotator._reset_view_all
passes a 2-element list [_ax_trace_x, _ax_trace_y] to
scope the refit to the trace pair when the cursor is over
one of them.
-
add_key_binding(key_name: str, on_press_function: callable, description: str = None, *, group: str | None = None, on_button: bool = False)
Add a key binding to the browser.
- Parameters:
key_name – Key to bind (matplotlib key-event string, e.g. “s”,
“ctrl+a”, “shift+left”).
on_press_function – Function to call when the key is pressed.
description – Human-readable label shown in the cheatsheet.
Defaults to on_press_function.__name__.
group – Section header in the cheatsheet dialog. None
falls into the “Other” section (rendered last).
on_button – When True, find a button whose action_func
is identically on_press_function and append
" ({key_name})" to its label. The match is by is
comparison — pass the same callable object to both
Buttons.add() and this method (no intermediate
lambdas) or the hint won’t attach. Resolution is
symmetric: if the button is added after the binding,
Buttons.add() performs the same scan.
-
remove_key_binding(key_name: str)
Remove a key binding from the browser.
- Parameters:
key_name (str) – Key to remove the binding for.
-
set_default_keybindings()
Set default key bindings for navigation.
-
increment(step: int = 1)
Increment the current index.
- Parameters:
step (int, optional) – Number of steps to increment. Defaults to 1.
-
decrement(step: int = 1)
Decrement the current index.
- Parameters:
step (int, optional) – Number of steps to decrement. Defaults to 1.
-
go_to_start()
Go to the start of the data.
-
go_to_end()
Go to the end of the data.
-
increment_frac(n_steps: int = 20)
Browse the entire dataset in n_steps. Increment the current index by a fraction of the total length.
- Parameters:
n_steps (int, optional) – Number of steps to divide the total length into. Defaults to 20.
-
decrement_frac(n_steps: int = 20)
Decrement the current index by a fraction of the total length.
- Parameters:
n_steps (int, optional) – Number of steps to divide the total length into. Defaults to 20.
-
copy_to_clipboard()
Copy the current figure window to the clipboard.
On a Qt backend, grabs the entire QMainWindow – the
matplotlib canvas plus every Qt-side widget parented to it
(left-column dock with buttons / statevariables, fast_render
image pane, downstream sidebars added by consumers such as
DUSTrack). The pre-rc2 path savefig’d the figure alone and
missed all of them; on a DUSTrack window the clipboard image
would show the trace canvas with nothing where the sidebar /
image pane visually sat.
On non-Qt backends (Agg, headless), falls back to copying just
the matplotlib figure via savefig.
Requires a Qt binding (PyQt5 / PyQt6 / PySide2 / PySide6); imported
lazily via qtpy so installs without Qt still get the rest of
the package. pip install datanavigator[qt] pulls PyQt6.
-
show_key_bindings()
Open the keyboard-shortcut cheatsheet.
On a Qt-backed figure: a modeless QDialog with one section
per KeyBinding.group (insertion order; None group
rendered last as “Other”). Each section is a 2-column table —
monospace shortcut on the left, description on the right.
On non-Qt backends: prints the same content to stdout. The
pre-rc2 TextView overlay is gone; matplotlib doesn’t host a
nice cheatsheet without the Qt path.
-
pan(direction: str = 'left', frac: float = 0.2)
Pan the view.
- Parameters:
direction (str, optional) – Direction to pan. Defaults to “left”.
frac (float, optional) – Fraction of the view to pan. Defaults to 0.2.
-
has(asset_type: str) → bool
Check if the browser has a specific asset type.
- Parameters:
asset_type (str) – Type of asset to check for.
- Returns:
True if the asset type is present, False otherwise.
- Return type:
bool
Module for browsing and visualizing time series data.
- Classes:
SignalBrowser: A browser for navigating through an array of pysampled.Data elements or 2D arrays.
-
class datanavigator.signals.SignalBrowser(plot_data: list[pysampled.core.Data], titlefunc: Callable | None = None, figure_handle: Figure | None = None, reset_on_change: bool = False, signal_names: list[str] | None = None, show_signal_dropdown: bool = True)
Browse an array of pysampled.Data elements, or 2D arrays.
-
update(event=None)
Update the browser.
- Parameters:
event (optional) – Event that triggered the update. Defaults to None.
-
add_signal_dropdown(names: list[str] | None = None, var_name: str = 'signal') → StateVariable
Add the signal-selection dropdown (a thin wrapper).
Delegates to GenericBrowser.add_item_dropdown() with a
"signal" row label. names=None derives labels from each
entry’s name (falling back to "signal <i>" via
_default_item_names()). See add_item_dropdown() for the
full contract: idempotent relabeling, Qt vs text rendering, and the
two-way _current_idx binding.
Module for browsing and visualizing data using customizable plotting functions.
- Classes:
PlotBrowser: A browser for navigating through a list of data objects and visualizing them using custom plotting functions.
-
class datanavigator.plots.PlotBrowser(plot_data: list, plot_func: tuple[callable, callable] | callable, figure_handle: plt.Figure = None, item_names: list[str] | None = None, show_item_dropdown: bool = True, **plot_kwargs)
Takes a list of data, and a plotting function (or a pair of setup
and update functions) that parses each of the elements in the array.
Assumes that the plotting function is going to make one figure.
-
add_selectors()
-
get_current_data()
Data getter. Plotting data is a list of objects that are being
plotted one at a time. This function returns the current object.
-
update(event: Any = None)
Update the browser.
Module for browsing videos and extracting clips from videos.
- Classes:
VideoBrowser: Scroll through the frames of a video, extract clips of interest.
VideoPlotBrowser: Browse a video and an array of pysampled.Data side by side.
-
class datanavigator.videos.VideoBrowser(vid_name: str, titlefunc: ~typing.Callable | None = None, figure_or_ax_handle: ~matplotlib.axes._axes.Axes | ~matplotlib.figure.Figure | None = None, image_process_func: ~typing.Callable = <function VideoBrowser.<lambda>>, fast_render: bool = False)
Scroll through the frames of a video, extract clips of interest.
If figure_handle is an axis handle, the video will be plotted in that axis.
- Future Enhancements:
Extend VideoBrowser to play, pause, and extract clips using hotkeys.
Show timeline in VideoBrowser.
Add clickable navigation.
-
increment_frac(n_steps: int = 100) → None
Browse entire dataset in n_steps.
- Parameters:
n_steps (int) – Number of steps to increment.
-
decrement_frac(n_steps: int = 100) → None
Browse entire dataset in n_steps.
- Parameters:
n_steps (int) – Number of steps to decrement.
-
update() → None
Update the video frame.
Extract a clip from the video.
- Parameters:
start_frame (Optional[int]) – Starting frame of the clip.
end_frame (Optional[int]) – Ending frame of the clip.
fname_out (Optional[str]) – Output filename.
out_rate (Optional[int]) – Output frame rate.
- Returns:
Path to the extracted clip.
- Return type:
str
-
class datanavigator.videos.VideoPlotBrowser(vid_name: str, signals: Dict[str, Data], titlefunc: Callable | None = None, figure_handle: Figure | None = None, event_win: tuple | None = None)
Browse a video and an array of pysampled.Data side by side.
- Parameters:
vid_name (str) – Path to the video file.
signals (Dict[str, pysampled.Data]) – Dictionary of signals.
titlefunc (Optional[Callable]) – Function to generate the title for the plot.
figure_handle (Optional[plt.Figure]) – Handle to the figure.
event_win (Optional[tuple]) – Event window. Visualize signals around an event. Use this to create “scrolling” plot visualizations, e.g. [-0.5, 1.].
-
update() → None
Update the video frame and signals.
-
onclick(event) → None
Right click mouse to seek to that frame.
- Parameters:
event – Matplotlib event.
Save a video of screengrabs.
- Parameters:
start_frame (Optional[int]) – Starting frame of the clip. Defaults to the first memory slot.
end_frame (Optional[int]) – Ending frame of the clip. Defaults to the second memory slot.
sav_dir (Optional[str]) – Directory to save the clip. If not provided, a timestamped directory is created.
- Returns:
Path to the saved video file.
This module is for visualizing and interacting with time series data that
can be analyzed using dimesionality reduction techniques such as PCA. It
was originally developed to visualize and classify periodic motion data
during running.
-
class datanavigator.components.ComponentBrowser(data: ndarray, data_transform: ndarray, labels: ndarray | None = None, figure_handle: Figure | None = None, class_names: dict[int, str] | None = None, desired_class_names: dict[int, str] | None = None, annotation_names: dict[int, str] | None = None)
-
property n_signals: int
Return the number of signals.
-
property n_timepts: int
Return the number of time points.
-
property colors: list[tuple]
Return the colors for each class.
-
property signal: Data
Return the 2D Numpy array as a signal.
-
select_signal_piece_dblclick(event: Any) → None
Double click a signal piece in the timecourse view to highlight that point.
- Parameters:
event (Any) – The mouse event.
-
onpick(event: Any) → None
Single click a projected point.
- Parameters:
event (Any) – The pick event.
-
update() → None
Update the plot with the current data index.
-
update_class_info_text(draw: bool = True) → None
Update the class info text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_desired_class_info_text(draw: bool = True) → None
Update the desired class info text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_mode_text(draw: bool = True) → None
Update the mode text.
- Parameters:
draw (bool) – Whether to draw the plot after updating.
-
update_message_text(text: str, draw: bool = True) → None
Update the message text.
- Parameters:
-
-
toggle_mode(event: Any | None = None) → None
Toggle between correction and annotation modes.
- Parameters:
event (Any | None) – The key event.
-
update_colors(data_idx: list[int] | None = None, draw: bool = True) → None
Update the colors of the plot.
- Parameters:
-
-
update_all() → None
Update all components of the plot.
-
clear_axes(event: Any | None = None) → None
Clear the axes.
- Parameters:
event (Any | None) – The key event.
-
classlabels_to_dict() → dict[int, dict[str, int | str | list[str]]]
Convert class labels to a dictionary.
- Returns:
Dictionary of class labels.
- Return type:
dict[int, dict[str, int | str | list[str]]]
-
set_classlabels(classlabels_dict: dict[int, dict[str, int | str | list[str]]]) → None
Set class labels from a dictionary.
- Parameters:
classlabels_dict (dict[int, dict[str, int | str | list[str]]]) – Dictionary of class labels.
-
class datanavigator.components.ClassLabel(label: int, name: str | None = None, assignment_type: str = 'auto', annotations: list[str] | None = None, original_label: int | None = None)
-
property color: tuple
Return the color of the class.
-
property label: int
Return the class label.
-
is_auto() → bool
Return whether the class label was assigned automatically.
- Returns:
True if the class label was assigned automatically, False otherwise.
- Return type:
bool
-
is_manual() → bool
Return whether the class label was assigned manually.
- Returns:
True if the class label was assigned manually, False otherwise.
- Return type:
bool
-
set_auto() → None
Set the class label assignment type to automatic.
-
set_manual() → None
Set the class label assignment type to manual.
-
add_annotation(annot: str) → None
Add an annotation to the class instance.
- Parameters:
annot (str) – The annotation to add.
Assets
Assets that power the functionality of the GenericBrowser class.
This module provides classes and functions for managing various assets such as buttons, selectors, and state variables in a graphical user interface.
- Classes:
Button - Add a ‘name’ state to a matplotlib widget button.
StateButton - Store a number/coordinate in a button.
ToggleButton - Add a toggle button to a matplotlib figure.
Selector - Select points in a plot using the lasso selection widget.
StateVariable - Manage state variables with multiple states.
AssetContainer - Container for managing assets such as buttons, memory slots, etc.
Buttons - Manager for buttons in a matplotlib figure or GUI.
Selectors - Manager for selector objects for picking points on line2D objects.
MemorySlots - Manager for memory slots to store and navigate positions.
StateVariables - Manager for state variables.
-
datanavigator.assets.apply_shortcut_hint(button, key_name: str) → None
Append " (key_name)" to button’s visible label.
Used by the keybinding cheatsheet wiring: when a binding declared
on_button=True matches a button (by action_func identity),
we want the shortcut visible on the button face. Handles both
backends:
mpl Button / ToggleButton carry a
matplotlib.text.Text label at .label. Toggle buttons
rebuild the label every state flip via set_text(); we patch
.name so the suffix survives across toggles.
The Qt-path _QtPushButton / _QtToggleButton wrappers (in
_qt) expose .name + ._qt_btn; we mutate .name
and call setText (push) or set_text() (toggle, which
rebuilds from name).
Idempotent on the same key_name: if the suffix is already
present, returns without re-appending.
-
class datanavigator.assets.Button(ax, name: str, **kwargs)
Add a ‘name’ state to a matplotlib widget button.
-
class datanavigator.assets.StateButton(ax, name: str, start_state: Any, **kwargs)
Store a number/coordinate in a button.
-
class datanavigator.assets.ToggleButton(ax, name: str, start_state: bool = True, **kwargs)
Add a toggle button to a matplotlib figure.
For example usage, see PlotBrowser.
-
set_text() → None
Set the text of the toggle button.
-
toggle(event=None) → None
Toggle the state of the button.
-
set_state(state: bool) → None
Set the state of the button.
-
class datanavigator.assets.Selector(plot_handle: Line2D)
Select points in a plot using the lasso selection widget.
Indices of selected points are stored in self.sel.
Example
f, ax = plt.subplots(1, 1)
ph, = ax.plot(np.random.rand(20))
plt.show(block=False)
ls = gui.Lasso(ph)
ls.start()
– play around with selecting points –
ls.stop() -> disconnects the events
-
get_data() → ndarray
Get the data points of the plot.
-
onselect(verts: List[tuple]) → None
Select if not previously selected; Unselect if previously selected.
-
start(event=None) → None
Start the lasso selection.
-
stop(event=None) → None
Stop the lasso selection.
-
toggle(event=None) → None
Toggle the lasso selection.
-
class datanavigator.assets.AssetContainer(parent: Any)
Container for assets such as a button, memoryslot, etc.
- Parameters:
parent (Any) – matplotlib figure, or something that has a ‘figure’ attribute that is a figure.
-
property names: List[str]
-
add(asset: Any) → Any
Add an asset to the container.
-
remove(name: str) → Any
Remove and return the asset with this name.
Counterpart to add(); raises KeyError if no asset in
the container carries that name. The caller is responsible for
tearing down any plot handles / Qt widgets the asset owns –
AssetContainer only manages the membership list.
-
class datanavigator.assets.Buttons(parent: Any)
Manager for buttons in a matplotlib figure or GUI (see GenericBrowser for example).
Phase 3 of the 1.4.0 Qt refactor (soft mode): when the parent’s figure
is on a Qt canvas AND no explicit pos is given, add() builds a
native QPushButton in a QVBoxLayout column hosted by a QDockWidget on
the QMainWindow’s LeftDockWidgetArea (pre-rc2: QToolBar; see
_qt._get_buttons_widget()). On every other backend, or when
an explicit pos is given, the original matplotlib-widgets path
runs unchanged. The returned object exposes the same public surface
either way (name, on_clicked, plus toggle-specific state
/ toggle / set_text / set_state).
Lifecycle gotcha: Buttons.add() reads the figure’s canvas at call
time. If a Figure subclass adds buttons inside its own __init__
(as in datanavigator.examples.ButtonDemo), this runs before
matplotlib attaches a Qt canvas to the figure, so those buttons end
up on the mpl path even under QtAgg. The buttons still function;
they just miss the Phase 3 perf win. Browsers that take a
figure_handle (the common case) are unaffected, because the figure
is fully constructed before any button is added.
rc2 row-cursor note: _mpl_row_cursor tracks the next vertical
slot for the mpl-fallback layout independent of len(self).
add() and add_separator() used to derive y from len(self),
which assumed one button per row. add_multi() (one row, N
buttons) breaks that assumption, so the cursor is bumped by 1 per
row (regardless of how many buttons land on it) while len(self)
still grows by N. For single-add-only flows the two stay equal,
preserving pre-rc2 placement.
-
add(text: str = 'Button', action_func: Callable | List[Callable] | None = None, pos: tuple | None = None, w: float = 0.25, h: float = 0.05, buf: float = 0.01, type_: str = 'Push', style_tag: str | None = None, **kwargs) → Button
Add a button to the parent figure / object.
If pos is provided, then w, h, and buf will be ignored.
-
register_style(name: str, styler: Callable[[Any], None]) → None
Register a per-button styler under name.
Consumers call this once at setup, then pass style_tag=name
to add() / add_multi(). Re-registering an existing
name (including a styles built-in) replaces the binding
– consumer registrations always win over built-ins.
styler is invoked with the freshly-constructed button as its
sole argument at the tail of _finalize_button(). It should
detect the Qt path via getattr(b, "_qt_btn", None) and apply
QSS / palette manipulation; mpl-path styling is the styler’s
choice (the dnav built-ins no-op there).
-
reapply_styles() → None
Re-run the styler for every already-added button.
Useful after register_style() changes a binding (e.g. a
theme swap re-registers "primary" with a dark-mode palette
and the existing buttons need to repaint).
-
add_multi(*specs: dict) → List[Any]
Add N buttons side-by-side in a single row.
Each spec is a dict of kwargs accepted by add() –
typically {text=..., action_func=..., type_=...}. Returns the
list of created button objects in spec order.
On the Qt path, all N buttons are children of a single QWidget
with a QHBoxLayout inserted into the buttons column’s
QVBoxLayout; the row therefore consumes one vertical slot in the
sidebar regardless of N. On the mpl fallback path, the row’s
width is divided evenly across N buttons at a shared y, and
_mpl_row_cursor is bumped by 1 (not N) so a following
add() lands on the next row, not N rows down.
Edge cases:
- add_multi() with no specs is a no-op and returns [].
- add_multi(one_spec) is equivalent to add(**one_spec) –
full-width single button – and returns a one-element list.
-
add_separator(name: str | None = None, style: str = 'single') → None
Add a visual group boundary between buttons.
On the Qt path (figure on a Qt canvas), inserts a sunken
QFrame.HLine into the buttons-column QVBoxLayout – a
thin line marking a group boundary. style="double" inserts
two stacked HLines for a stronger section break, used by
DUSTrack to mark major button groups in its rc2 sidebar. On
the mpl path, inserts one (or two, for style="double")
invisible buttons that occupy layout slots so subsequent
buttons are pushed down. (Pre-rc2 the Qt-path inserted a
QToolBar.addSeparator() QAction; single-HLine only.)
Promoted to a first-class API for downstream consumers (DUSTrack)
that previously hand-rolled invisible spacers by mutating
matplotlib.widgets.Button internals (.ax, .label,
.ax.patch) – internals that don’t exist on the Qt path.
- Parameters:
-
-
class datanavigator.assets.Selectors(parent: Any)
Manager for selector objects - for picking points on line2D objects.
-
add(plot_handle: Line2D) → Selector
Add a selector to the container.
-
class datanavigator.assets.MemorySlots(parent: Any)
Manager for memory slots to store and navigate positions.
-
static initialize() → dict
Initialize memory slots.
-
disable() → None
Disable memory slots.
-
enable() → None
Enable memory slots.
-
show(pos: str = 'bottom left') → None
Show memory slot text.
-
update(key: str) → None
Handle memory slot updates.
Initiate when None, go to the slot if it exists, free slot if pressed when it exists.
key is the event.key triggered by a callback.
-
update_display() → None
Refresh memory slot text if it is not hidden.
-
hide() → None
Hide the memory slot text.
-
is_enabled() → bool
Check if memory slots are enabled.
-
class datanavigator.assets.StateVariable(name: str, states: list, widget: str = 'label')
Manage state variables with multiple states.
The widget hint is metadata read by the rc2 Qt sidebar to choose
a control surface for this state variable: "label" (read-only
text line; default), "dropdown" (QComboBox), or "toggle"
(mutually-exclusive row of checkable QToolButtons). On non-Qt
backends the hint is ignored and the value renders as plain text
via the legacy TextView path.
-
property current_state: Any
Get the current state.
-
n_states() → int
Get the number of states.
-
add_on_change(callback: Callable[[], None]) → None
Register a no-arg callback fired after state mutations.
Fires on every set_state() / cycle() /
cycle_back() call, regardless of whether the index
actually changed – consumers that need a real-change guard
should track the previous value themselves (e.g.
VideoPointAnnotator._on_active_label_change()).
-
cycle() → None
Cycle to the next state.
-
cycle_back() → None
Cycle to the previous state.
-
set_state(state: int | str) → None
Set the state.
-
class datanavigator.assets.StateVariables(parent: Any)
Manager for state variables.
-
asdict() → dict
Return state variables as a dictionary.
-
add(name: str, states: list, widget: str = 'label') → StateVariable
Add a state variable to the container.
- Parameters:
name – identifier; must be unique within the container.
states – the rotation of values this variable can take.
widget – rc2 Qt-sidebar control surface hint – one of
"label" (read-only text; default; matches pre-rc2
behavior), "dropdown" (QComboBox), or "toggle"
(mutually-exclusive QToolButton row). Ignored on non-Qt
backends.
-
show(pos: str = 'bottom right', fax=None) → None
Show state variables.
rc2: tries the interactive Qt widget first (dropdowns / toggles
/ labels per each StateVariable’s widget hint),
mounted in the QDockWidget column beneath the buttons. Falls
back to the pre-rc2 utils.TextView path on non-Qt
backends or if no Qt window is found. The pos / fax
arguments are only consulted on the TextView fallback; on the
Qt path they’re ignored (the widget’s position is dock-managed).
-
update_display(draw: bool = True) → None
Update the display of state variables.
This module provides classes and functions for managing events and event data.
- Classes:
EventData - Manage the data from one event type in one trial.
Event - Manage selection of a sequence of events.
Events - Manager for event objects.
-
class datanavigator.events.EventData(default: list | None = None, added: list | None = None, removed: list | None = None, tags: list | None = None, algorithm_name: str = '', params: dict | None = None)
Manage the data from one event type in one trial.
- Variables:
default (list) – Default events created by an algorithm.
added (list) – Manually added events. Note that if an ‘added’ point is removed, then it will simply be deleted. There will be no record of it.
removed (list) – Events removed from the default list.
tags (list) – Tags associated with the events.
algorithm_name (str) – Name of the algorithm used to generate the default list.
params (dict) – Parameters used to generate the default list.
-
asdict() → dict
Convert the event data to a dictionary.
-
get_size() → int
Return the size of the envent, for example, 2 for start and stop events.
-
get_times() → list
Get the times of all events.
-
to_portions() → _PNInterval
Convert the event times to portions.
-
overlap_duration(other: 'portion.Interval' | tuple) → float
Calculate the duration of overlap with another interval.
-
class datanavigator.events.Event(name: str, size: int, fname: str, data_id_func: ~typing.Callable | None = <function Event.<lambda>>, color: str | int = 'random', pick_action: str = 'overwrite', ax_list: list | None = None, win_remove: tuple[float, float] = (-0.1, 0.1), win_add: tuple[float, float] = (-0.25, 0.25), data_func: ~typing.Callable = <class 'float'>, **plot_kwargs)
Manage selection of a sequence of events (of length >= 1).
- Variables:
name (str) – Name of the event.
size (int) – Length of the sequence.
fname (str) – File name to load and save events.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
color (str) – Color of the event. Defaults to a random color.
pick_action (str) – Action to take when picking an event (‘overwrite’ or ‘append’). Use overwrite if there can only be one sequence per ‘signal’. If there can be multiple, use ‘append’. Defaults to overwrite
ax_list (list) – list of axes on which to show the event.
win_remove (tuple) – Window relative to the mouse position to search for removing an event. Defaults to (-0.1, 0.1).
win_add (tuple) – Window relative to the mouse position to search for adding an event. Defaults to (-0.25, 0.25).
data_func (Callable) – Function to process the data.
plot_kwargs (dict) – Keyword arguments for plotting. Commonly used keys are ‘display_type’ (line or fill) and ‘alpha’ to set the transparency level.
-
classmethod from_file(fname: str, **kwargs) → Event
Create an empty events file with the given file name (fname) and any parameters.
Assigns best-guess defaults.
-
classmethod from_data(data: dict, name: str = 'Event', fname: str = '', overwrite: bool = False, **kwargs) → Event
Create an event file by filling in the ‘default’ events extracted by an algorithm.
- Parameters:
data (dict) – Data to create the event file.
name (str) – Name of the event.
fname (str) – File name to save the event.
overwrite (bool) – Whether to overwrite the existing file.
**kwargs – Additional keyword arguments.
tags, algorithm_name, and params will be passed to EventData.
All other keyword arguments will be passed to Event.
- Returns:
The created Event object.
- Return type:
Event
-
all_keys_are_tuples() → bool
Check if all keys are tuples.
Get the header information of the event.
-
load() → tuple[dict, dict]
Load the event data from the file.
-
save() → None
Save the event data to the file.
-
add(event: Any) → None
Pick the time points of an interval and associate it with a supplied ID.
If the first selection is outside the axis, then select the first available time point.
If the last selection is outside the axis, then select the last available time point.
If the selections are not monotonically increasing, then empty the buffer.
If any of the ‘middle’ picks (i.e. not first or last in the sequence) are outside the axes, then empty the buffer.
The parent UI would invoke this method.
- Parameters:
event (Any) – The event to add.
-
remove(event: Any) → None
Remove an event.
- Parameters:
event (Any) – The event to remove.
-
get_current_event_times() → list
Get the current event times.
-
setup_display() → None
Setup event display on one or more axes.
-
update_display(draw: bool = True) → None
Update the event display.
-
to_dict() → dict
Convert the event data to a dictionary.
-
to_portions() → dict
Convert the event data to portions.
-
class datanavigator.events.Events(parent: Any)
Manager for Event objects.
-
add(name: str, size: int, fname: str, data_id_func: ~typing.Callable, color: str | int, pick_action: str = 'overwrite', ax_list: list | None = None, win_remove: tuple[float, float] = (-0.1, 0.1), win_add: tuple[float, float] = (-0.25, 0.25), add_key: str | None = None, remove_key: str | None = None, save_key: str | None = None, show: bool = True, data_func: ~typing.Callable = <class 'float'>, **plot_kwargs) → Event
Add an event.
- Parameters:
name (str) – Name of the event.
size (int) – Length of the sequence. For example, if this is 2, then the event is a pair of start and end times.
fname (str) – File name to save the event.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
color (str | int) – Color used to display the event
pick_action (str, optional) – Action to take when picking an event (‘overwrite’ or ‘append’). Use overwrite if there can only be one sequence per ‘signal’. If there can be multiple, use ‘append’. Defaults to overwrite. Defaults to ‘overwrite’.
ax_list (list | None, optional) – list of axes on which to show the event. Defaults to None.
win_remove (tuple[float, float], optional) – Window relative to the mouse position to search for removing an event. Defaults to (-0.1, 0.1).
win_add (tuple[float, float], optional) – Window relative to the mouse position to search for adding an event. Defaults to (-0.25, 0.25). For future use.
add_key (str | None, optional) – Keyboard shortcut for adding the event. Defaults to None.
remove_key (str | None, optional) – Keyboard shortcut for removing the event. Defaults to None.
save_key (str | None, optional) – Keyboard shortcut for saving the events to a JSON file. Defaults to None.
show (bool, optional) – Event visibility. Defaults to True.
data_func (Callable, optional) – Function to apply on the incoming event. Intended use is for type casting. Defaults to float.
- Returns:
_description_
- Return type:
Event
-
add_from_file(fname: str, data_id_func: ~typing.Callable, ax_list: list | None = None, add_key: str | None = None, remove_key: str | None = None, save_key: str | None = None, show: bool = True, data_func: ~typing.Callable = <class 'float'>, **plot_kwargs) → Event
Add events from an existing file.
Intended use case - events are created by another algorithm meant to be edited using a browser in the datanavigator.
- Parameters:
fname (str) – File name to load the events.
data_id_func (Callable) – Function to get the current data ID from the parent UI.
ax_list (list | None, optional) – list of axes on which to show the event. Defaults to None.
add_key (str | None, optional) – Keyboard shortcut for adding the event. Defaults to None.
remove_key (str | None, optional) – Keyboard shortcut for removing the event. Defaults to None.
save_key (str | None, optional) – Keyboard shortcut for saving the events to a JSON file. Defaults to None.
show (bool, optional) – Event visibility. Defaults to True.
data_func (Callable, optional) – Function to apply on the incoming event. Intended use is for type casting. Defaults to float.
- Returns:
The created Event object.
- Return type:
Event
-
setup_display() → None
Setup display for all events.
-
update_display(draw: bool = True) → None
Update display for all events
Utilities
Utility functions and classes for video processing and plotting.
This module provides various utility functions and classes to assist with
video processing, plotting, and other miscellaneous tasks.
-
datanavigator.utils.ticks_from_times(times: List[float], tick_lim: Tuple[float, float]) → Tuple[List[float], List[float]]
Generate x, y arrays to supply to plt.plot function to plot a set of x-values (times) as ticks.
- Parameters:
times (List[float]) – List of time values.
tick_lim (Tuple[float, float]) – Limits for the y-axis ticks.
- Returns:
x and y arrays for plotting ticks.
- Return type:
Tuple[List[float], List[float]]
-
datanavigator.utils.find_nearest(x, y)
Find the nearest x-values for every value in y.
- Parameters:
-
- Returns:
List with the same length as y, where each element is the value in x
closest to the corresponding element of y.
-
datanavigator.utils.find_nearest_idx_val(array, value)
Index and value of the element in array closest to value.
- Parameters:
-
- Returns:
Tuple (idx, val) where idx is the index of the nearest entry
in array and val is that entry.
-
datanavigator.utils.find_nearest_idx(array, value)
Index of the element in array closest to value.
- Parameters:
-
- Returns:
Integer index of the nearest entry in array.
-
datanavigator.utils.find_nearest_val(array, value)
Value in array closest to value.
- Parameters:
-
- Returns:
The entry of array closest to value.
-
class datanavigator.utils.TextView(text: List[str] | dict, fax: None | Figure | Axes = None, pos: str | Tuple[float, float, str, str] = 'bottom left')
Show text array line by line.
Phase 2 of the 1.4.0 Qt refactor (soft mode): when fax resolves to
a figure whose canvas is a matplotlib Qt canvas, the text renders as a
native QLabel overlay parented to the canvas (self._overlay set,
self._text stays None). On every other backend the original
Axes.text path runs unchanged (self._overlay is None,
self._text is the mpl Text artist).
The public surface (__init__ signature, .text, .update)
is identical across both paths.
-
parse_text(text: List[str] | dict) → List[str]
Parse text input into a list of strings.
- Parameters:
text (Union[List[str], dict]) – Text input.
- Returns:
Parsed text.
- Return type:
List[str]
-
setup() → None
Setup for showing the text.
-
update(new_text: List[str] | dict = None) → None
Update the text view with new text.
- Parameters:
new_text (Union[List[str], dict], optional) – New text to display. Defaults to None.
-
datanavigator.utils.get_palette(palette_name: str = 'Set2', n_colors: int = 10) → List[Tuple[float, float, float]]
Get a color palette, with fallback if seaborn is not available.
- Parameters:
palette_name (str, optional) – Name of the palette. Defaults to “Set2”.
n_colors (int, optional) – Number of colors. Defaults to 10.
- Returns:
List of RGB tuples.
- Return type:
List[Tuple[float, float, float]]
-
datanavigator.utils.is_video(vid_file: str)
-
class datanavigator.utils.Video(uri: str, ctx=cpu(0), width: int = -1, height: int = -1, num_threads: int = 0, fault_tol: int = -1)
Extended VideoReader class with additional methods.
-
gray(frame_num: int) → ndarray
Convert a frame to grayscale.
- Parameters:
frame_num (int) – Frame number to convert.
- Returns:
Grayscale frame.
- Return type:
np.ndarray
-
datanavigator.utils.removeprefix(s: str, prefix: str) → str
Remove the specified prefix from the string, if present.
- Parameters:
-
- Returns:
The string with the prefix removed, if it starts with the prefix.
- Return type:
str
-
datanavigator.utils.removesuffix(s: str, suffix: str) → str
Remove the specified suffix from the string, if present.
- Parameters:
-
- Returns:
The string with the suffix removed, if it ends with the suffix.
- Return type:
str
-
datanavigator.utils.is_pathname_valid(pathname: str) → bool
True if the passed pathname is a valid pathname for the current OS;
False otherwise.
-
datanavigator.utils.is_path_creatable(pathname: str) → bool
True if the current user has sufficient permissions to create the passed
pathname; False otherwise.
-
datanavigator.utils.is_path_exists_or_creatable(pathname: str) → bool
True if the passed pathname is a valid pathname for the current OS _and_
either currently exists or is hypothetically creatable; False otherwise.
This function is guaranteed to _never_ raise exceptions.
Point tracking + optical flow (relocated)
The point-tracking UI, annotation containers
(VideoAnnotation / VideoAnnotations), and Lucas-Kanade helpers
(lucas_kanade / lucas_kanade_rstc) relocated to the
DUSTrack package in 1.5.0
alongside its DeepLabCut workflow. See
dustrack.DUSTrack
for the new home.