Visualisation#
Multiple purpose-built live display windows — each dark-themed, Qt-native, and fully thread-safe. Push data from a background acquisition thread; all rendering happens on the main Qt thread via an internal 30 Hz timer.
RawPlot
Multi-channel scrolling M/EEG raw signal viewer
Dark-themed multi-channel raw signal display. All channels are stacked vertically with colour-coded traces and channel-name Y-axis labels, modelled on the standard M/EEG browser layout. All signal processing is applied from now: enabling a filter or re-reference leaves existing buffer data intact and processes only newly incoming chunks. A built-in Riemannian Potato detector can automatically flag artefacted segments in real time.
info is provided
raw_plot.to_annotations()
raw_plot = RawPlot(
ch_names=info["ch_names"],
sfreq=1000,
info=info, # enables SSP projector checkbox
)
raw_plot.show()
# background acquisition thread:
raw_plot.push(chunk) # shape (n_channels, n_samples)
See mne_rt.viz.RawPlot for the full API reference.
EpochPlot
Scrolling viewer with live epoch and trigger overlays
Same dark-themed scrolling display as RawPlot, extended with visual
epoch markers. Each stimulus event (push_trigger) draws three
overlays in a per-condition colour: a solid vertical line
at t = 0, a semi-transparent shaded band spanning
[tmin, tmax], and dashed boundary lines at the epoch edges.
The epoch window is adjustable live without stopping the stream.
Event colours are distinct (green, cyan, yellow, …).
ep = EpochPlot(
ch_names=info["ch_names"],
sfreq=1000,
event_id={"target": 1, "standard": 2},
tmin=-0.1,
tmax=0.5,
)
ep.show()
ep.push(chunk) # continuous data — shape (n_ch, n_samples)
ep.push_trigger(1) # mark event code 1 at the current position
See mne_rt.viz.EpochPlot for the full API reference.
NFPlot
Scrolling real-time neurofeedback signal monitor
A scrolling dark-themed multi-channel NF feature monitor. One colour-coded trace per active neurofeedback modality is updated live as each analysis window completes. The amplitude scale is adjustable on the fly and each modality gets a distinct hue for instant visual separation.
nf_plot = NFPlot("alpha", "beta", "gamma") # one trace per modality
nf_plot.show()
# inside the acquisition loop:
nf_plot.push({"alpha": alpha_val, "beta": beta_val, "gamma": gamma_val})
See mne_rt.viz.NFPlot for the full API reference.
ButterflyPlot
All channels overlaid per condition with region colour gradient
All channels overlaid in a single panel per condition, coloured by scalp region: blue (frontal) → cyan → green → amber → red (occipital). The gradient makes spatial ERP patterns instantly readable and outlier channels visually obvious without any manual channel selection.
butt = ButterflyPlot(
ch_names=ch_names,
sfreq=1000,
tmin=-0.1,
tmax=0.5,
event_id={"left": 1, "right": 2},
montage="easycap-M1",
)
butt.update(epochs, conditions)
See mne_rt.viz.ButterflyPlot for the full API reference.
CompareEvoked
Per-channel large plots with all conditions overlaid and peak markers
Large individual plots per electrode with all conditions overlaid, ±1 SEM shading, and a scatter dot marking the peak latency in the post-stimulus window. Channels are selected by clicking on a clickable mini scalp-topomap in the sidebar — making it trivially easy to drill into any electrode without hunting through a list.
cmp = CompareEvoked(
ch_names=ch_names,
sfreq=1000,
tmin=-0.1,
tmax=0.5,
event_id={"left": 1, "right": 2},
montage="easycap-M1",
)
cmp.update(epochs, conditions)
See mne_rt.viz.CompareEvoked for the full API reference.
TopoPlot
Scalp-layout evoked display — one mini plot per electrode
One mini plot per electrode placed at its true 2-D scalp position
(from mne.channels.find_layout). Condition averages
with ±1 SEM shading re-render after every accepted trial, giving an
instant whole-brain view of the evolving ERP.
Re-referencing, smoothing, and y-scale are all adjustable from the sidebar.
topo = TopoPlot(
ch_names=ch_names,
sfreq=1000,
tmin=-0.1,
tmax=0.5,
event_id={"left": 1, "right": 2},
montage="easycap-M1",
)
topo.update(epochs, conditions) # call after each accepted trial
See mne_rt.viz.TopoPlot for the full API reference.
TopomapPlot
Live per-band power scalp topographic map
Live scalp topographic map that displays the spatial distribution of per-band power in real time. Built on MNE-Python's matplotlib pipeline with a Qt canvas, it refreshes continuously as new data windows arrive. Electrode positions are overlaid and a custom frequency range can be typed directly into the sidebar without restarting.
tmap = TopomapPlot(
info=raw_info,
sfreq=1000,
frange=(8, 13), # start with the alpha band
)
tmap.show()
tmap.push(data_window) # shape (n_channels, n_samples)
See mne_rt.viz.TopomapPlot for the full API reference.
TFRPlot
Morlet wavelet time-frequency heatmaps across conditions
Morlet wavelet TFR heatmaps arranged in a (channels × conditions) grid. Two modes: induced (average of per-epoch TFR) and evoked (TFR of the trial average). Colour limits are shared across conditions for direct comparison. Channels are selected via a clickable sidebar topomap — the same click-to-inspect paradigm used in CompareEvoked.
import numpy as np
tfr = TFRPlot(
ch_names=ch_names,
sfreq=1000,
tmin=-0.1,
tmax=0.5,
freqs=np.arange(4, 40),
event_id={"left": 1, "right": 2},
montage="easycap-M1",
)
tfr.update(epochs, conditions)
See mne_rt.viz.TFRPlot for the full API reference.
BrainPlot
Interactive 3-D cortical surface with colour-mapped source activity
Interactive 3-D cortical surface rendered with PyVista, with colour-mapped source-space activity that updates live as new NF windows arrive. Hemisphere toggles, surface switching, anatomical parcellation borders, and a full set of view presets make it the most feature-rich display in the suite. Video recording (MP4) is built in.
brain = BrainPlot(
subjects_fs_dir="/path/to/freesurfer",
surf="inflated",
clim=[0, 0.6],
display_smoothing=5,
)
brain.show()
brain.push(stc_data) # source-space activity array
See mne_rt.viz.BrainPlot for the full API reference.