mne_rt.viz.NFPlot#
- class mne_rt.viz.NFPlot(modalities: list[str], scales_dict: dict[str, float], sfreq: float, time_window: float = 30.0, display_smoothing: float = 0.3, verbose=None)[source]#
Bases:
_MockQMainWindowScrolling real-time neurofeedback signal monitor.
Displays one colour-coded trace per active NF modality in a dark-themed
pyqtgraph.PlotWidget. Designed to be driven byrecord_main()viapush().- Parameters:
- modalities
listofstr Names of the active NF modalities. One scrolling trace is shown per entry. Names must match entries in
_LABELSfor a human-readable legend, or the raw string is used as a fallback.- scales_dict
dict[str,float] Mapping from modality name to its physical display scale. The raw NF value is divided by this scale before plotting so that all traces occupy a similar vertical range.
- sfreq
float Nominal update rate in Hz. Used to size the ring buffer.
- time_window
float, default 30.0 Visible time range in seconds at startup (can be changed at runtime from the control panel).
- verbosebool |
str|None, defaultNone Verbosity level. See
set_log_level().
- modalities
See also
mne_rt.viz.BrainPlot3D brain activation display.
mne_rt.viz.RawPlotScrolling raw M/EEG channel viewer.
mne_rt.RTStream.record_mainDrives both plots from the NF loop.
Notes
The control panel (right sidebar) provides:
Playback — pause/resume, clear buffer, screenshot.
Display — time-window selector, grid toggle, threshold-line toggle, reward-zone toggle, auto-range.
Channel Scales — per-modality amplitude scaling with
+/−buttons and a live×Nreadout.
Each subplot can show a dashed horizontal threshold line marking the reward boundary of the protocol driving that modality (fixed or adaptive), passed per-update via the
thresholdsargument ofpush(). A modality with no associated protocol, or one whose protocol has no single-level threshold (e.g.LinearTrendProtocol), simply shows no line.Each subplot can also show a translucent green reward span behind the trace, scrolling in lock-step with it, marking windows where the driving protocol currently rewards the subject — passed per-update via the
rewardsargument ofpush(). A modality with no driving protocol simply shows no span.Status bar shows the latest value — and, when available, the current threshold — for every active modality, prefixed with 🟢 during reward.
Examples
Minimal offline usage:
>>> app = QApplication([]) >>> plot = NFPlot(["sensor_power"], {"sensor_power": 1e-12}, sfreq=100) >>> plot.show() >>> plot.push([3.2e-13], thresholds=[2.0e-13], rewards=[True]) >>> app.exec()
Added in version 1.0.0.
- __init__(modalities: list[str], scales_dict: dict[str, float], sfreq: float, time_window: float = 30.0, display_smoothing: float = 0.3, verbose=None) None[source]#
Methods
__init__(modalities, scales_dict, sfreq[, ...])closeEvent(event)push(new_vals[, thresholds, rewards])Append one new sample per modality and refresh all traces.
Attributes
Emitted when the window is closed, before Qt tears down the widget.
- closed = <MagicMock name='mock.Signal()' id='140412836434064'>#
Emitted when the window is closed, before Qt tears down the widget.
record_main()connects this to stop pumping new data into a closed window while other plot windows stay open.
- push(new_vals: list[float], thresholds: list[float | None] | None = None, rewards: list[bool | None] | None = None) None[source]#
Append one new sample per modality and refresh all traces.
This is the main update entry point, called at ~30 fps by the Qt pump timer inside
record_main().- Parameters:
- new_vals
listoffloat Latest NF value for each active modality, in the same order as the
modalitieslist passed to__init__().- thresholds
listof(floatorNone), optional Current reward-threshold value for each modality, in the same raw units as
new_vals(i.e. not pre-normalised). Omit entirely to leave threshold lines untouched; useNoneornanfor an individual entry to hide that modality’s line (e.g. a modality with no protocol, or a protocol with no single-level threshold such asLinearTrendProtocol). Typically sourced from a protocol’scurrent_thresholdproperty — seerecord_main().- rewards
listof(bool orNone), optional Whether the driving protocol is currently rewarding the subject for each modality, i.e. the
crossedhalf of that protocol’sevaluate()return value. Rendered as a translucent green span behind the trace, scrolling in lock-step with it. Omit entirely to leave reward spans untouched; useNonefor an individual entry when the modality has no driving protocol.
- new_vals
Notes
The call is a no-op when the plot is paused (⏸ button pressed). Each value is normalised by its entry in
scales_dictbefore being written into the ring buffer, so all traces share a common vertical scale. Threshold values are normalised the same way so the dashed threshold line stays aligned with its trace, including after per-channel+/−scale adjustments.