Version 1.13.0.dev197+ge1da4c068 (development) (2026-07-28)#
Dependencies#
Updated minimum for:
Core dependency
matplotlib >= 3.9
Changes implemented via CI action created by Thomas Binns. (#13899)
Updated minimum for:
Optional dependency
scikit-learn >= 1.5
Changes implemented via CI action created by Thomas Binns. (#13916)
Switch the default Qt bindings from PyQt6 to PySide6. As a result,
mne[full]now includes PySide6 instead of PyQt6. Users who prefer PyQt6 can continue to usemne[full-pyqt6], andmne[full-pyside6]remains available as an alias formne[full]. Changes by Clemens Brunner. (#13960)PyQt5 is no longer an officially supported Qt binding, by Eric Larson. (#13981)
Updated minimum for:
Core dependency
numpy >= 2.0, < 3Core dependency
scipy >= 1.14
Changes implemented via CI action created by Thomas Binns. (#14023)
Updated minimum for:
Optional dependency
pyvista >= 0.44
Changes implemented via CI action created by Thomas Binns. (#14048)
Raised minimum versions of some optional dependencies to comply with MNE-Python’s SPEC0-like policy, and added them to the set kept up to date automatically by the
spec_zeroCI job, by Eric Larson:Optional dependency
dipy >= 1.9Optional dependency
mne-qt-browser >= 0.6Optional dependency
nibabel >= 5.2Optional dependency
nilearn >= 0.10Optional dependency
numba >= 0.60(#14108)
Bugfixes#
Fixed a bug in
mne.stats.spatio_temporal_cluster_1samp_test()and related spatio-temporal permutation cluster functions where, in rare cases, clusters that should have been joined by a chain of spatial and temporal adjacency steps were incorrectly reported as separate clusters, by Sharif Haason. (#13731)Fix
modeparameter inget_point_spread()andget_cross_talk()to correctly map public mode names ('max','svd') to internal names, expose previously hidden modes'sum'and'maxval'in the public API, and raiseValueErrorfor invalid mode values, by new contributor Famous077. (#13754)Improved colocated OPM topomap handling by recognizing additional OPM coil types (FieldLine and Kernel), by Pragnya Khandelwal. (#13825)
Fix bug where logging messages were sometimes errantly printed, by Eric Larson. (#13843)
Fixed incorrect label orientation for nodes in the 0–90° polar range (the 12–3 o’clock quadrant) of the connectivity circle plot, by new contributor Pavel Popov. (#13855)
Fixed an indexing bug in fNIRS support in
mne.io.BaseRaw.interpolate_bads()(and related methods) that could errantly use incorrect donor channels, by new contributor Kalle Makela. (#13856)Add a
memmapkeyword argument tomne.io.BaseRaw.load_data(), allowing loading deferred raw data into a memory-mapped file after object creation, by Aniket Singh Yadav. (#13858)Completed triaxial OPM topomap grouping by rendering separate radial and tangential maps in
plot_evoked_topomap()andplot_components(), and fixed shape-mismatch crashes inplot_projs_topomap()andanimate_topomap()with colocated OPM channels, by Pragnya Khandelwal. (#13866)Fix handling of optional dependencies that don’t specify a version attribute, by new contributor Baris Talar. (#13870)
Improved error message when FreeSurfer executable is not found, by new contributor Ayushi Satodiya. (#13874)
Fix bug with
mne.preprocessing.ICA.plot_properties()when usingrejectinmne.preprocessing.ICA.fit(), by Eric Larson. (#13885)Fix bug where
pickswas ignored inmne.Epochs.apply_function()whenchannel_wise=False, by Thomas Binns. (#13894)Fix iteration errors in
mne.io.read_raw_nihon()when reading log files, by Tom Ma. (#13915)Fix bug with
mne.set_eeg_reference()not working when passing a single channel name as string, by Michael Straube. (#13917)Fix
mne.set_eeg_reference()so that passing a list of channel types withprojection=Falseandref_channels="average"now references each channel type independently by default (matching theprojection=Truepath), by new contributor Ben Tang. Previously a single average was computed across the union of the listed types. Passjoint=Truefor the previous behavior. (#13920)Use mffpy-backed parsing for EGI MFF event tracks while tolerating nanosecond timestamps that some files store in
beginTime, by Pragnya Khandelwal. (#13932)Fix
mne.preprocessing.eyetracking.interpolate_blinks()so that all annotation descriptions passed viamatchare interpolated over, rather than onlyBAD_blinkones, by new contributor Vincent Gao. (#13940)Fix channel ordering bug in
mne.viz.plot_compare_evokeds()whenaxes="topo", by Lifeng Qiu Lin. (#13943)Fix bug in
mne.read_annotations()where reading a.txtfile containing a single channel-specific annotation raised anAttributeError, by new contributor Piotr Durka. (#13962)Fixed bug where
mne.sys_info()would silently change the active Matplotlib backend (e.g. whenipymplis installed) as an import-time side effect, by Stefan Appelhoff. (#13963)Fix bug where
mne.preprocessing.write_fine_calibration()wrote internalMEGchannel names (e.g.MEG0113) instead of the bare channel numbers (e.g.113) that MaxFilter expects, breaking round trips of Neuromag calibration files, by new contributor Apoorva Verma. (#13999)Fix
mne.preprocessing.eyetracking.read_eyelink_calibration()to decode.ascfiles as UTF-8 instead of ASCII, so non-ASCII characters inMSGlines no longer raise aUnicodeDecodeError, by new contributor Cedric Conday. (#14002)Fix the error message raised when a requested FIR
filter_lengthis too short, which reported half the actual transition bandwidth, by Cedric Conday. (#14005)Fixed several error messages that displayed literal
{...}placeholder text instead of the intended values, due to a missingfstring prefix (inmne.SourceEstimate,mne.io.read_raw_hitachi(),mne.preprocessing.compute_current_source_density(), andmne.preprocessing.maxwell_filter()), by Cedric Conday. (#14008)Fix bug where
mne.concatenate_epochs()could silently concatenate epochs with conflictingevent_iddicts, by Eric Larson. (#14051)Fixed two bugs in how SSS information is stored and read:
mne.preprocessing.maxwell_filter()recorded which multipole moments it had kept in the wrong order (the filtered data itself was unaffected), andmne.compute_rank()reported the full MEG rank rather than the reduced SSS rank for data processed with MaxFilter™-3.0, by Eric Larson. (#14059)Fix figures not being displayed in notebook-style frontends when using a Matplotlib inline backend, by Mingjian He. (#14076)
Fix Qt browser close messages from
mne.io.Raw.plot()appearing in the wrong Jupyter notebook cell, by Mingjian He. (#14077)When concatenating
Rawobjects containing annotations, also merge theextrasfields, by Marijn van Vliet (#14084)Fixed
plot_evoked_topomap()andplot_sensors()(and theplot_sensorsmethods) to follow Matplotlib’s blocking behavior whenshow=Trueinstead of returning immediately;plot_sensorskeeps itsblockargument (default nowNone), by Clemens Brunner. (#14098)Fixed bug in
mne.io.Raw.plot()where, with the matplotlib backend andgroup_by="selection", the channel-selection radio buttons no longer all appeared selected while in butterfly mode, by Eric Larson. (#14108)
API changes by deprecation#
Rename
standard_1005andstandard_1020montages tocolin27_1005andcolin27_1020, respectively. If you usedstandard_1005orstandard_1020, either switch to the new namescolin27_1005andcolin27_1020or use the new spherical montagesspherical_1005,spherical_1010, orspherical_1020, which provide idealized template locations on a sphere (useful for plotting). By Clemens Brunner. (#13903)In
mne.Evoked.animate_topomap()thevminandvmaxkeyword arguments have been deprecated in favor ofvlim, by Eric Larson. (#13905)In
mne.viz.iter_topography(), theon_pickcallable for sub-figures now has a new parameterorig_figthat refers to the main figure. To preserve backward compatibility, it is made optional. By Lifeng Qiu Lin. (#13968)The
blockparameter ofmne.time_frequency.Spectrum.plot_topo(), the legacyplot_psd_topomethods, andmne.viz.plot_raw_psd_topois deprecated and will be removed in MNE 1.15; these plots now follow Matplotlib’s blocking behavior, by Clemens Brunner. (#14098)
New features#
Add
mne.preprocessing.eyetracking.find_blinks()to detect blinks in eye-tracking data from pupil dropouts and return them asAnnotations, by Stefan Appelhoff. (#12946)It is now possible to concatenate raw objects with
mne.concatenate_raws()as long as they inherit fromBaseRaw, even if their specific types differ (e.g.,RawandRawArray), by Clemens Brunner. (#13263)Add a preprocessing example showing how to explore epoch quality before rejection using robust statistics (peak-to-peak amplitude, variance, and kurtosis) inspired by FASTER (Nolan et al., 2010) and Delorme et al. (2007), by Aman Srivastava. (#13710)
Speed up
mne.stats.spatio_temporal_cluster_1samp_test()and related permutation cluster functions via precomputed sum-of-squares for sign-flip t-tests and SciPy connected-components clustering (~5x), by new contributor Sharif Haason. (#13731)Add
annotation_colorsparameter tomne.io.Raw.plot()andmne.Epochs.plot()to allow users to specify custom colors for annotations by passing a dict mapping annotation description strings to colors (for example,annotation_colors=dict(bad_segment="orange")), by Clemens Brunner. (#13838)Add dark theme support (
theme="light","dark", or"auto") to the'matplotlib'browser backend used bymne.io.Raw.plot(),mne.Epochs.plot(), andmne.preprocessing.ICA.plot_sources(), by Clemens Brunner. (#13861)Fix
mne.preprocessing.nirs.beer_lambert_law()to support explicitly providedsd_distancesduring Beer-Lambert conversion. When valid source-detector distances are already present inraw.info, overriding them now emits a warning, and when all inferred distances are invalid and no explicit distances are provided, aValueErroris raised instead of silently producing zero concentrations, by new contributor Kalle Makela. (#13875)Add
overridesparameter tomne.io.read_raw_brainvision()for reading non-spec-compliant.vhdrfiles where the header contradicts the actual layout (e.g. renamed BIDS siblings, missingMarkerFile=, truncated[Channel Infos]). Accepts a dict with keysdata_fname,marker_fname,n_channels,sfreq,ch_names,units_fallback,data_orientation,data_format, andbinary_format; see the function docstring for details. Missing or emptyMarkerFile=is now also tolerated natively (per the BV Core Data Format spec). WhenMarkerFile=names a path that does not exist (common after BIDS renames),mne.io.read_raw_brainvision()now falls back to the co-located<stem>.vmrknext to the.vhdrand warns, instead of raisingFileNotFoundError, by Bruno Aristimunha. (#13884)Add idealized spherical 10–05, 10–10, and 10–20 montages (
spherical_1005,spherical_1010,spherical_1020), by Clemens Brunner. (#13903)Improved
mne.Reportby:Using
"agg"backend for 2D plots to avoid windows unnecessarily popping upImproving
add_stc()by using direct capture of brain images, allowing direct control of image size usingstc_plot_kwargs["size"]Improving
add_evokeds()evoked topomap plotting by usingmne.Evoked.animate_topomap()withbutterfly=Truerather than re-plotting each topomap in a loop
Also improved
mne.Evoked.animate_topomap()by deduplicating code withmne.Evoked.plot_topomap(). Changes by Eric Larson. (#13905)Add support for reading cross-talk and fine-calibration embedded in FIF files during acquisition into
raw.info["cross_talk"]andraw.info["fine_calibration"], respectively, by Eric Larson. (#13911)Add support for interactive label browsing using
hover=Trueinmne.viz.Brain.add_annotation(), by Eric Larson. (#13931)Added
'fsaverage_1005'montage, which is a slightly improved version of the existing'colin27_1005'montage (known in 1.12 and older as'standard_1005'). The electrodes have already been mapped to thefsaveragehead surface. Changes by Eric Larson. (#13936)Added basic support for TD fNIRS data, by new contributor Zahra Aghajan, new contributor Julien Dubois, new contributor John Griffiths, Robert Luke, and Eric Larson. (#13938)
Add support for automatic
cross_talkandfine_calibrationadjustments inmne.preprocessing.maxwell_filter()when these are stored inmne.Infoduring acquisition (e.g., by newer MEGIN acquisition software), by Eric Larson. (#13942)Added the
n_componentsparameter to ICA plotting and report generation functions to allow dynamic control over the number of components displayed by Athish M. (#13958)Added a
volume_options["interpolation"]option tomne.viz.plot_source_estimates()andmne.viz.Brain.add_data()to control the interpolation method used for volume rendering. It can be"linear"(default) or"nearest". Changes by Eric Larson. (#13966)Include label and description fields when reading EGI mff files, by Martin Oberg. (#13967)
Add
TimeChangebehaviour formne.viz.plot_evoked_topo(), where time is marked with solid vertical line after clicking on subfigure axis. Addrecursiveparameter tomne.viz.ui_events.link()that enables linking to a target figure, as well as all figures that the target figure links to, by Lifeng Qiu Lin. (#13968)Add
mask_label_paramsparameter toplot_topomap()andplot_evoked_topomap()to allow for customisation of masked channel labels, by Carina Forster. (#13969)Added public
mne.viz.LayeredMeshclass (previously private_LayeredMesh) with asmooth_matattribute for efficient real-time source-space data streaming. AddedBrain.layered_meshesattribute to access meshes after plotting, and akeyparameter tomne.viz.Brain.add_data()for named overlays, by new contributor Payam Sadeghi-Shabestari. (#13970)Skip replotting of annotations on the horizontal scrollbar in the matplotlib browser backend, resulting in a significant speedup for traces with a large number of annotations by Frankie Robertson. (#13972)
Allow subclasses of
MNEBrowseFigureto be passed to plot_raw/plot_epochs, as well as the correspondingplot(...)methods of the raw and epochs classes, by new contributor Frankie Robertson (#13979)Add mouse wheel scrolling support to the
'matplotlib'browser backend to navigate through channels, by Clemens Brunner. (#13988)add_data()now supports multiple simultaneous overlays viaremove_existing=Falseand distinctkeyvalues. Theremove_existingparameter now acceptsTrue/Falsein addition toNone. By Payam Sadeghi-Shabestari. (#13995)Add
on_outsideparameter tomne.Epochsandmne.EpochsArrayclasses to control the behaviour when events exist outside the data range. The options are to'warn'(new default),'raise', or'ignore'(old behaviour), by Cedric Conday. (#14004)mne.viz.Brain’ssilhouetteoption now accepts a spacing string (e.g."ico5", now the default) to decimate using the same vertex-picking asmne.setup_source_space()instead of a generic mesh decimation.mne.viz.plot_alignment()andmne.viz.Brainshould also be faster when plotting many sensors (e.g., whole-head MEG systems), by Eric Larson. (#14016)Add a
show_zero_lineparameter (and 0 keyboard shortcut) tomne.io.Raw.plot()andmne.Epochs.plot()to show a reference line at each channel’s zero, by Clemens Brunner. (#14018)Make
mne.viz.plot_evoked_topo()show the currently select time with a solid vertical line also in the main figure, by Marijn van Vliet. (#14032)Added a
weightedoption tomne.chpi.compute_head_pos()that fits all cHPI coils simultaneously with per-coil weights derived from their goodness of fit and inter-coil distance error, avoiding discontinuous jumps (“teleporting”) in the estimated head position caused by coils switching in and out of the best-three subset (#11330). The default will change fromFalsetoTruein version 1.14; until then, leaving it unset emits aFutureWarning. By Eric Larson. (#14034)More complete type checking has been implemented for
mne.io, plusEpochsandEvoked, by Eric Larson. (#14036)When multiple overlays are active (via
remove_existing=Falseinadd_data()), the interactive Brain viewer now shows an “Overlay” drop-down in the Color Limits dock panel that lets the user switch which overlay’s color limits and smoothing the sliders control. By Payam Sadeghi-Shabestari. (#14037)Make the vertical (channel) and horizontal (time) scrollbar handles in the
'matplotlib'browser backend draggable, by Clemens Brunner. (#14040)The colorbar in the
mne.viz.Brainviewer now automatically switches to scientific notation for tick labels, and has more tick-label spacing. The Help dialog now uses a Qt dialog styled to matchmne-qt-browser’s help dialog instead of amatplotlibpopup, and the “Press ? for help” status bar message is now clickable, and “Help” text was removed from the top left of the GUI by Payam Sadeghi-Shabestari. (#14054)Added support for newer recording software in
mne.io.read_raw_nirx(), by Emma Bailey. (#14055)Added type annotations to public members of
mne/io,mne.Evoked, andmne.Epochs, by Eric Larson. (#14056)Sped up
mne.stats.spatio_temporal_cluster_1samp_test()by graph reduction and more efficiently applying sign-flips, by Eric Larson. (#14057)mne.viz.plot_ica_components()andmne.preprocessing.ICA.plot_components()now set the window title to “Independent Components” instead of adding a suptitle and append the plotted component range when it is contiguous, by Clemens Brunner. (#14058)Added
regularize="in_argmax"tomne.preprocessing.maxwell_filter()to allow component selection more similar to that of MaxFilter™-2.2, by Eric Larson. (#14059)Speed up and slightly improved the accuracy of
mne.make_forward_solution(), by Eric Larson. (#14061)The colorbar in the
mne.viz.Brainviewer now shows tick marks aligned with its labels, and its title now defaults to the active overlay’skey(seeadd_data()). The interactive viewer can show vertex coordinates and camera orientation, toggled via the v key or a new toolbar button, by Payam Sadeghi-Shabestari. (#14062)On Linux,
mne.sys_info()now includes the detected windowing system (Wayland or X11), by Clemens Brunner. (#14099)
Other changes#
Adopting the diataxis framework by improving the phantom dipole tutorial, by Carina Forster. (#13584)
Reorganized EDF submodule structure by moving private functionality into the public
mne.ionamespace to improve module consistency and avoid exposing private modules in the Credits page, by Aniket Singh Yadav. (#13673)Document
onset,duration,description, andch_namesattributes ofmne.Annotations, by Famous077. (#13680)Remove
numpy.ndarrayfromcolormapparameter inmne.viz.plot_source_estimates()to solve documentation conflict , by new contributor Lifeng Qiu Lin. (#13797)Added cross-references to common modification methods in
mne.Infodocstring by new contributor Athish M. (#13811)Adding checks in
mne.stats.permutation_t_test()to warn the user when provided with bad input values, by Himanshu Mahor. (#13813)Added regression coverage for colocated triaxial OPM topomap handling in
plot_joint()andICA.plot_components(), by Pragnya Khandelwal. (#13842)Add notes to
set_eeg_reference()and Setting the EEG reference about the correct procedure to create an average reference, by new contributor Deep Kaur and new contributor Farzah11. (#13846)Added a helper to split colocated OPM overlap sets into radial and tangential channel groups, and updated topomap regression coverage to use shared triaxial OPM fixtures, by Pragnya Khandelwal. (#13847)
Fixed typos in error messages when reading measurement info, by new contributor Seth Bashford. (#13881)
Fixed the
funshape description inmne.Epochs.apply_function()’s docstring, by new contributor Bhargav Kowshik. (#13891)Batch and vectorise classifier estimation and scoring in
mne.decoding.GeneralizingEstimator.score()forscoring=None,"accuracy","balanced_accuracy"and"roc_auc", by new contributor Mathias Sablé-Meyer. (#13909)Convert non-empty
drop_logentries fromnumpy.str_to regular Python strings, by Clemens Brunner. (#13923)Refactor the EGI MFF reader to use
mffpyfor metadata parsing, improving robustness and maintainability. This includes a shim for PNS sensor parsing to bypass an upstream bug inmffpyand resolves channel naming inconsistencies, by Pragnya Khandelwal. (#13945)Replace the internal binary-block EEG sample reader in
mne.io.read_raw_egi()withmffpy-backed reading viamffpy.Reader.get_physical_samples_from_epoch, removing manual block-header parsing andnp.fromfilecalls, by Pragnya Khandelwal. (#13973)Converted the remaining percent-style string formatting to f-strings in internal code, by new contributor Théo Castillo. (#13974)
Replace
defusedxml-backed implementations of_get_ep_infoand_get_signalfnamein the EGI MFF reader withmffpy-backed parsing viamne.io.read_raw_egi(), by Pragnya Khandelwal. (#13991)Replace
defusedxml-backed_get_gainswithmffpy-backed parsing viamne.io.read_raw_egi()and remove the internal_extracthelper, fully eliminatingdefusedxmlfrom the EGI MFF reader, by Pragnya Khandelwal. (#14007)Add table with all available config options to Configuring MNE-Python, by Clemens Brunner. (#14010)
Remove
_get_eeg_calibration_infofrom the EGI MFF reader and delegate per-channel GCAL scaling tomffpy’s native calibration, simplifying EEG channel calibration inmne.io.read_raw_egi(), by Pragnya Khandelwal. (#14011)Replace the manual PNS binary block reader in
mne.io.read_raw_egi()withmffpy-backed reading viaget_physical_samples_from_epoch, by Pragnya Khandelwal. (#14030)Replace manual binary block reader
_get_blockswithmffpy.ReaderAPI in_read_mff_header, removing low-level EGI binary parsing in favour of the existing mffpy dependency, by Pragnya Khandelwal. (#14043)Remove dead placeholder keys
gain,bits, andvalue_rangefrom_read_headerinegimff.py; these were hardcoded to zero and unused since MFF calibration is handled viaCAL_SCALES, by Pragnya Khandelwal. (#14047)Document how to check and tune the OpenBLAS thread count when decomposition-heavy operations are unexpectedly slow, by new contributor Daria Agafonova. (#14064)