14 KiB
EEG Analysis and Microstates
Overview
Analyze electroencephalography (EEG) signals for frequency band power, channel quality assessment, source localization, and microstate identification. NeuroKit2 integrates with MNE-Python for comprehensive EEG processing workflows.
Core EEG Functions
eeg_power()
Compute power across standard frequency bands for specified channels.
power = nk.eeg_power(eeg_data, sampling_rate=250, channels=['Fz', 'Cz', 'Pz'],
frequency_bands={'Delta': (0.5, 4),
'Theta': (4, 8),
'Alpha': (8, 13),
'Beta': (13, 30),
'Gamma': (30, 45)})
Standard frequency bands:
- Delta (0.5-4 Hz): Deep sleep, unconscious processes
- Theta (4-8 Hz): Drowsiness, meditation, memory encoding
- Alpha (8-13 Hz): Relaxed wakefulness, eyes closed
- Beta (13-30 Hz): Active thinking, focus, anxiety
- Gamma (30-45 Hz): Cognitive processing, binding
Returns:
- DataFrame with power values for each channel × frequency band combination
- Columns:
Channel_Band(e.g., 'Fz_Alpha', 'Cz_Beta')
Use cases:
- Resting state analysis
- Cognitive state classification
- Sleep staging
- Meditation or neurofeedback monitoring
eeg_badchannels()
Identify problematic channels using statistical outlier detection.
bad_channels = nk.eeg_badchannels(eeg_data, sampling_rate=250, bad_threshold=2)
Detection methods:
- Standard deviation outliers across channels
- Correlation with other channels
- Flat or dead channels
- Channels with excessive noise
Parameters:
bad_threshold: Z-score threshold for outlier detection (default: 2)
Returns:
- List of channel names identified as problematic
Use case:
- Quality control before analysis
- Automatic bad channel rejection
- Interpolation or exclusion decisions
eeg_rereference()
Re-express voltage measurements relative to different reference points.
rereferenced = nk.eeg_rereference(eeg_data, reference='average', robust=False)
Reference types:
'average': Average reference (mean of all electrodes)'REST': Reference Electrode Standardization Technique'bipolar': Differential recording between electrode pairs- Specific channel name: Use single electrode as reference
Common references:
- Average reference: Most common for high-density EEG
- Linked mastoids: Traditional clinical EEG
- Vertex (Cz): Sometimes used in ERP research
- REST: Approximates infinity reference
Returns:
- Re-referenced EEG data
eeg_gfp()
Compute Global Field Power - the standard deviation of all electrodes at each time point.
gfp = nk.eeg_gfp(eeg_data)
Interpretation:
- High GFP: Strong, synchronized brain activity across regions
- Low GFP: Weak or desynchronized activity
- GFP peaks: Points of stable topography, used for microstate detection
Use cases:
- Identify periods of stable topographic patterns
- Select time points for microstate analysis
- Event-related potential (ERP) visualization
eeg_diss()
Measure topographic dissimilarity between electric field configurations.
dissimilarity = nk.eeg_diss(eeg_data1, eeg_data2, method='gfp')
Methods:
- GFP-based: Normalized difference
- Spatial correlation
- Cosine distance
Use case:
- Compare topographies between conditions
- Microstate transition analysis
- Template matching
Source Localization
eeg_source()
Perform source reconstruction to estimate brain-level activity from scalp recordings.
sources = nk.eeg_source(eeg_data, method='sLORETA')
Methods:
'sLORETA': Standardized Low-Resolution Electromagnetic Tomography- Zero localization error for point sources
- Good spatial resolution
'MNE': Minimum Norm Estimate- Fast, well-established
- Bias toward superficial sources
'dSPM': Dynamic Statistical Parametric Mapping- Normalized MNE
'eLORETA': Exact LORETA- Improved localization accuracy
Requirements:
- Forward model (lead field matrix)
- Co-registered electrode positions
- Head model (boundary element or spherical)
Returns:
- Source space activity estimates
eeg_source_extract()
Extract activity from specific anatomical brain regions.
regional_activity = nk.eeg_source_extract(sources, regions=['PFC', 'MTL', 'Parietal'])
Region options:
- Standard atlases: Desikan-Killiany, Destrieux, AAL
- Custom ROIs
- Brodmann areas
Returns:
- Time series for each region
- Averaged or principal component across voxels
Use cases:
- Region-of-interest analysis
- Functional connectivity
- Source-level statistics
Microstate Analysis
Microstates are brief (80-120 ms) periods of stable brain topography, representing coordinated neural networks. Typically 4-7 microstate classes (often labeled A, B, C, D) with distinct functions.
microstates_segment()
Identify and extract microstates using clustering algorithms.
microstates = nk.microstates_segment(eeg_data, n_microstates=4, sampling_rate=250,
method='kmod', normalize=True)
Methods:
'kmod'(default): Modified k-means optimized for EEG topographies- Polarity-invariant clustering
- Most common in microstate literature
'kmeans': Standard k-means clustering'kmedoids': K-medoids (more robust to outliers)'pca': Principal component analysis'ica': Independent component analysis'aahc': Atomize and agglomerate hierarchical clustering
Parameters:
n_microstates: Number of microstate classes (typically 4-7)normalize: Normalize topographies (recommended: True)n_inits: Number of random initializations (increase for stability)
Returns:
- Dictionary with:
'maps': Microstate template topographies'labels': Microstate label at each time point'gfp': Global field power'gev': Global explained variance
microstates_findnumber()
Estimate the optimal number of microstates.
optimal_k = nk.microstates_findnumber(eeg_data, show=True)
Criteria:
- Global Explained Variance (GEV): Percentage of variance explained
- Elbow method: find "knee" in GEV curve
- Typically 70-80% GEV achieved
- Krzanowski-Lai (KL) Criterion: Statistical measure balancing fit and parsimony
- Maximum KL indicates optimal k
Typical range: 4-7 microstates
- 4 microstates: Classic A, B, C, D states
- 5-7 microstates: Finer-grained decomposition
microstates_classify()
Reorder microstates based on anterior-posterior and left-right channel values.
classified = nk.microstates_classify(microstates)
Purpose:
- Standardize microstate labels across subjects
- Match conventional A, B, C, D topographies:
- A: Left-right orientation, parieto-occipital
- B: Right-left orientation, fronto-temporal
- C: Anterior-posterior orientation, frontal-central
- D: Fronto-central, anterior-posterior (inverse of C)
Returns:
- Reordered microstate maps and labels
microstates_clean()
Preprocess EEG data for microstate extraction.
cleaned_eeg = nk.microstates_clean(eeg_data, sampling_rate=250)
Preprocessing steps:
- Bandpass filtering (typically 2-20 Hz)
- Artifact rejection
- Bad channel interpolation
- Re-referencing to average
Rationale:
- Microstates reflect large-scale network activity
- High-frequency and low-frequency artifacts can distort topographies
microstates_peaks()
Identify GFP peaks for microstate analysis.
peak_indices = nk.microstates_peaks(eeg_data, sampling_rate=250)
Purpose:
- Microstates typically analyzed at GFP peaks
- Peaks represent moments of maximal, stable topographic activity
- Reduces computational load and noise sensitivity
Returns:
- Indices of GFP local maxima
microstates_static()
Compute temporal properties of individual microstates.
static_metrics = nk.microstates_static(microstates)
Metrics:
- Duration (ms): Mean time spent in each microstate
- Typical: 80-120 ms
- Reflects stability and persistence
- Occurrence (per second): Frequency of microstate appearances
- How often each state is entered
- Coverage (%): Percentage of total time in each microstate
- Relative dominance
- Global Explained Variance (GEV): Variance explained by each class
- Quality of template fit
Returns:
- DataFrame with metrics for each microstate class
Interpretation:
- Changes in duration: altered network stability
- Changes in occurrence: shifting state dynamics
- Changes in coverage: dominance of specific networks
microstates_dynamic()
Analyze transition patterns between microstates.
dynamic_metrics = nk.microstates_dynamic(microstates)
Metrics:
- Transition matrix: Probability of transitioning from state i to state j
- Reveals preferential sequences
- Transition rate: Overall transition frequency
- Higher rate: more rapid switching
- Entropy: Randomness of transitions
- High entropy: unpredictable switching
- Low entropy: stereotyped sequences
- Markov test: Are transitions history-dependent?
Returns:
- Dictionary with transition statistics
Use cases:
- Identify abnormal microstate sequences in clinical populations
- Network dynamics and flexibility
- State-dependent information processing
microstates_plot()
Visualize microstate topographies and time course.
nk.microstates_plot(microstates, eeg_data)
Displays:
- Topographic maps for each microstate class
- GFP trace with microstate labels
- Transition plot showing state sequences
- Statistical summary
MNE Integration Utilities
mne_data()
Access sample datasets from MNE-Python.
raw = nk.mne_data(dataset='sample', directory=None)
Available datasets:
'sample': Multi-modal (MEG/EEG) example'ssvep': Steady-state visual evoked potentials'eegbci': Motor imagery BCI dataset
mne_to_df() / mne_to_dict()
Convert MNE objects to NeuroKit-compatible formats.
df = nk.mne_to_df(raw)
data_dict = nk.mne_to_dict(epochs)
Use case:
- Work with MNE-processed data in NeuroKit2
- Convert between formats for analysis
mne_channel_add() / mne_channel_extract()
Manage individual channels in MNE objects.
# Extract specific channels
subset = nk.mne_channel_extract(raw, ['Fz', 'Cz', 'Pz'])
# Add derived channels
raw_with_eog = nk.mne_channel_add(raw, new_channel_data, ch_name='EOG')
mne_crop()
Trim recordings by time or samples.
cropped = nk.mne_crop(raw, tmin=10, tmax=100)
mne_templateMRI()
Provide template anatomy for source localization.
subjects_dir = nk.mne_templateMRI()
Use case:
- Source analysis without individual MRI
- Group-level source localization
- fsaverage template brain
eeg_simulate()
Generate synthetic EEG signals for testing.
synthetic_eeg = nk.eeg_simulate(duration=60, sampling_rate=250, n_channels=32)
Practical Considerations
Sampling Rate Recommendations
- Minimum: 100 Hz for basic power analysis
- Standard: 250-500 Hz for most applications
- High-resolution: 1000+ Hz for detailed temporal dynamics
Recording Duration
- Power analysis: ≥2 minutes for stable estimates
- Microstates: ≥2-5 minutes, longer preferred
- Resting state: 3-10 minutes typical
- Event-related: Depends on trial count (≥30 trials per condition)
Artifact Management
- Eye blinks: Remove with ICA or regression
- Muscle artifacts: High-pass filter (≥1 Hz) or manual rejection
- Bad channels: Detect and interpolate before analysis
- Line noise: Notch filter at 50/60 Hz
Best Practices
Power analysis:
# 1. Clean data
cleaned = nk.signal_filter(eeg_data, sampling_rate=250, lowcut=0.5, highcut=45)
# 2. Identify and interpolate bad channels
bad = nk.eeg_badchannels(cleaned, sampling_rate=250)
# Interpolate bad channels using MNE
# 3. Re-reference
rereferenced = nk.eeg_rereference(cleaned, reference='average')
# 4. Compute power
power = nk.eeg_power(rereferenced, sampling_rate=250, channels=channel_list)
Microstate workflow:
# 1. Preprocess
cleaned = nk.microstates_clean(eeg_data, sampling_rate=250)
# 2. Determine optimal number of states
optimal_k = nk.microstates_findnumber(cleaned, show=True)
# 3. Segment microstates
microstates = nk.microstates_segment(cleaned, n_microstates=optimal_k,
sampling_rate=250, method='kmod')
# 4. Classify to standard labels
microstates = nk.microstates_classify(microstates)
# 5. Compute temporal metrics
static = nk.microstates_static(microstates)
dynamic = nk.microstates_dynamic(microstates)
# 6. Visualize
nk.microstates_plot(microstates, cleaned)
Clinical and Research Applications
Cognitive neuroscience:
- Attention, working memory, executive function
- Language processing
- Sensory perception
Clinical populations:
- Epilepsy: seizure detection, localization
- Alzheimer's disease: slowing of EEG, microstate alterations
- Schizophrenia: altered microstates, especially state C
- ADHD: increased theta/beta ratio
- Depression: frontal alpha asymmetry
Consciousness research:
- Anesthesia monitoring
- Disorders of consciousness
- Sleep staging
Neurofeedback:
- Real-time frequency band training
- Alpha enhancement for relaxation
- Beta enhancement for focus
References
- Michel, C. M., & Koenig, T. (2018). EEG microstates as a tool for studying the temporal dynamics of whole-brain neuronal networks: A review. Neuroimage, 180, 577-593.
- Pascual-Marqui, R. D., Michel, C. M., & Lehmann, D. (1995). Segmentation of brain electrical activity into microstates: model estimation and validation. IEEE Transactions on Biomedical Engineering, 42(7), 658-665.
- Gramfort, A., Luessi, M., Larson, E., Engemann, D. A., Strohmeier, D., Brodbeck, C., ... & Hämäläinen, M. (2013). MEG and EEG data analysis with MNE-Python. Frontiers in neuroscience, 7, 267.