Time-frequency analysis is essential for understanding how oscillatory brain activity changes over time in response to stimuli or during cognitive tasks. Unlike classical ERP analysis that focuses on time-domain averages, time-frequency methods reveal dynamic spectral changes in specific frequency bands (delta, theta, alpha, beta, gamma) that are often masked in traditional averaging.
Common neuroscience applications include:
PhysioEEG provides three complementary time-frequency decomposition methods, each with distinct advantages depending on your research question, signal characteristics, and required time-frequency resolution.
library(PhysioEEG)
# Create example EEG data: 64 channels, 1000 ms epochs, 100 trials, 500 Hz sampling
eeg <- make_eeg_erp(
n_channels = 64,
n_timepoints = 500,
n_trials = 100,
sampling_rate = 500
)
# Inspect dimensions
dim(assay(eeg, "raw")) # channels x timepoints x trials
samplingRate(eeg) # 500 HzThe Morlet wavelet transform provides excellent time-frequency resolution trade-off control via the number of cycles parameter. It convolves the signal with complex Morlet wavelets at specified frequencies, yielding both power and phase information.
Parameter selection:
n_cycles = f / 3 (e.g., 4 Hz → 1.3 cycles, 40 Hz → 13
cycles).# Morlet wavelet transform with frequency-dependent resolution
# Good for capturing both slow (theta) and fast (gamma) dynamics
eeg <- eegMorletWavelet(
eeg,
frequencies = seq(4, 40, by = 2), # 4-40 Hz in 2 Hz steps
n_cycles = seq(4, 40, by = 2) / 3, # Frequency-dependent: f/3 cycles
assay_name = "raw",
output_assay = "morlet_power"
)
# Output dimensions: channels x frequencies x timepoints x trials
dim(assay(eeg, "morlet_power"))
# For detailed alpha band analysis with higher frequency resolution
eeg <- eegMorletWavelet(
eeg,
frequencies = seq(8, 13, by = 0.5), # Fine-grained alpha range
n_cycles = 7, # Fixed 7 cycles for good frequency precision
assay_name = "raw",
output_assay = "alpha_power"
)When to use Morlet wavelets:
STFT divides the signal into short overlapping windows and computes the FFT for each segment. It provides uniform time-frequency resolution across all frequencies, determined by the window size.
Window size trade-offs:
# Standard STFT with 250 ms windows (good balance for cognitive EEG)
eeg <- eegSTFT(
eeg,
window_size = 125, # 250 ms at 500 Hz = 125 samples
overlap = 0.75, # 75% overlap for smooth representation
window_type = "hanning",
assay_name = "raw",
output_assay = "stft_power"
)
# Output: channels x frequencies x time_windows x trials
dim(assay(eeg, "stft_power"))
# For high temporal precision (e.g., rapid stimulus changes)
eeg <- eegSTFT(
eeg,
window_size = 50, # 100 ms windows
overlap = 0.50, # 50% overlap
window_type = "hanning",
assay_name = "raw",
output_assay = "stft_fast"
)
# For high frequency resolution (e.g., resting-state narrow-band analysis)
eeg <- eegSTFT(
eeg,
window_size = 500, # 1000 ms windows
overlap = 0.90, # High overlap to maintain some temporal detail
window_type = "hamming",
assay_name = "raw",
output_assay = "stft_fine"
)When to use STFT:
The Thomson multitaper method uses multiple orthogonal tapers (windowing functions) to reduce variance in spectral estimates while maintaining good frequency resolution. It provides robust spectral estimates, especially for stationary or quasi-stationary signals.
Parameter selection:
floor(2 * bandwidth * T - 1) where T is the time window
duration in seconds.# Multitaper analysis with 3 Hz bandwidth
# Good for reducing noise in oscillatory power estimates
eeg <- eegMultitaper(
eeg,
bandwidth = 3, # 3 Hz smoothing bandwidth
n_tapers = 5, # Use 5 Slepian tapers
assay_name = "raw",
output_assay = "multitaper_power"
)
# Output: channels x frequencies x timepoints x trials
dim(assay(eeg, "multitaper_power"))
# For high-frequency resolution (narrow-band analysis)
eeg <- eegMultitaper(
eeg,
bandwidth = 1.5, # Narrow bandwidth for fine frequency resolution
n_tapers = 3,
assay_name = "raw",
output_assay = "multitaper_narrow"
)When to use multitaper:
ITC measures phase consistency across trials at each time-frequency point, ranging from 0 (random phase) to 1 (perfect phase alignment). Unlike ERSP which captures power changes, ITC specifically identifies phase-locked (evoked) oscillatory activity.
Key concepts:
# Compute ITC from Morlet wavelet transform
# Uses complex wavelet coefficients to assess phase consistency
eeg <- eegITC(
eeg,
assay_name = "morlet_power" # Should be complex wavelet output
)
# ITC stored in metadata
itc_data <- metadata(eeg)$ITC
dim(itc_data) # channels x frequencies x timepoints
# Extract channel-specific ITC
fcz_itc <- itc_data[channelIndex(eeg, "FCz"), , ]
dim(fcz_itc) # frequencies x timepoints
# High ITC at low frequencies captures ERP phase-locking
# Check theta band (4-8 Hz) ITC time course
theta_itc <- apply(fcz_itc[4:8, ], 2, mean)
plot(theta_itc, type = "l", xlab = "Time (ms)", ylab = "ITC")Interpreting ITC:
Time-frequency heatmaps (spectrograms) are the standard visualization for ERSP, ITC, and raw power. PhysioEEG provides customizable spectrogram plotting with sensible defaults.
# Plot ERSP spectrogram for channel Pz
eegPlotSpectrogram(
eeg,
channel = "Pz",
freq_range = c(4, 40), # Focus on theta-gamma range
time_range = c(-200, 800), # Pre-stimulus to 800 ms post-stimulus
log_power = FALSE, # ERSP already in dB
palette = "RdBu", # Red-blue diverging palette (blue=ERD, red=ERS)
assay_name = "morlet_power"
)
# Plot ITC spectrogram
eegPlotSpectrogram(
eeg,
channel = "FCz",
freq_range = c(4, 30),
time_range = NULL, # Use full time range
log_power = FALSE,
palette = "viridis", # Sequential palette for ITC (0 to 1)
assay_name = "morlet_power"
)
# Plot raw power with log scaling
eegPlotSpectrogram(
eeg,
channel = "O1",
freq_range = c(8, 13), # Alpha band detail
time_range = c(0, 500),
log_power = TRUE, # Convert to dB scale
palette = "magma",
assay_name = "morlet_power"
)Visualization tips:
Choosing the right time-frequency method depends on your data characteristics, research question, and computational resources.
| Method | Time Resolution | Frequency Resolution | Best For | Computational Cost |
|---|---|---|---|---|
| Morlet Wavelet | Variable (tunable via n_cycles) | Variable (tunable via n_cycles) | Event-related designs, flexible resolution trade-off, cross-frequency coupling | Moderate-High (depends on # frequencies) |
| STFT | Uniform (set by window) | Uniform (set by window) | Continuous EEG, resting-state, fast computation, uniform resolution | Low-Moderate |
| Multitaper | Moderate | High (good for narrow bands) | Resting-state, low SNR, narrow-band oscillations, robust spectral estimates | Moderate |
Decision tree:
Epoched event-related data with precise timing requirements: Use Morlet wavelets with frequency-dependent n_cycles for optimal time-frequency resolution matching signal characteristics.
Continuous or resting-state EEG: Use STFT for speed or multitaper for robust spectral estimates with low variance.
Narrow-band oscillation detection (e.g., individual alpha frequency): Use multitaper with low bandwidth for superior frequency resolution.
Broad frequency range with varying dynamics: Use Morlet wavelets with frequency-dependent parameters (low n_cycles for low frequencies, high n_cycles for high frequencies).
Low signal-to-noise ratio: Use multitaper to reduce spectral variance, or average multiple Morlet wavelet trials.
Computational constraints: Use STFT, which is faster than wavelets when analyzing many frequencies.
Frequency resolution comparison:
Time resolution comparison: