Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/changes/latest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Enhancements

- Add :func:`mne.preprocessing.compute_bridged_electrodes` to detect EEG electrodes with shared spatial sources due to a conductive medium connecting two or more electrodes, add :ref:`ex-eeg-bridging` for an example and :func:`mne.viz.plot_bridged_electrodes` to help visualize (:gh:`10571` by `Alex Rockhill`_)

- Add ``'voronoi'`` as an option for the ``image_interp`` argument in :func:`mne.viz.plot_topomap` to plot a topomap without interpolation using a Voronoi parcelation (:gh:`10571` by `Alex Rockhill`_)
- Add ``'nearest'`` as an option for the ``interpolation`` argument in :func:`mne.viz.plot_topomap` to plot a topomap without interpolation using a Voronoi parcelation (:gh:`10571` by `Alex Rockhill`_)
Comment thread
alexrockhill marked this conversation as resolved.
Outdated

- Add :func:`mne.preprocessing.interpolate_bridged_electrodes` to use the spatially smeared signal to get a better interpolation rather than dropping those channels (:gh:`10587` by `Alex Rockhill`_)

Expand Down Expand Up @@ -97,3 +97,5 @@ API and behavior changes
- When creating BEM surfaces via :func:`mne.bem.make_watershed_bem` and :func:`mne.bem.make_flash_bem`, the ``copy`` parameter now defaults to ``True``. This means that instead of creating symbolic links inside the FreeSurfer subject's ``bem`` folder, we now create "actual" files. This should avoid troubles when sharing files across different operating systems and file systems (:gh:`10531` by `Richard Höchenberger`_)

- The ordering of channels returned by :func:`mne.io.read_raw_nirx` is now ordered by channel name, rather than the order provided by the manufacturer. This enables consistent ordering of channels across different file types (:gh:`10555` by `Robert Luke`_)

- For :func:`mne.viz.plot_topomap`, :func:`mne.viz.plot_evoked_topomap`, :func:`mne.viz.plot_arrowmap`, :func:`mne.viz.plot_ica_components`, :meth:`mne.Covariance.plot_topomap`, :meth:`mne.Evoked.plot_topomap`, :meth:`mne.Evoked.animate_topomap`, :meth:`mne.decoding.CSP.plot_patterns`, :meth:`mne.Projection.plot_topomap` and :meth:`mne.preprocessing.ICA.plot_components` the topomap image interpolation was previously a cubic interpolation but now can be ``'linear'`` and ``'nearest'`` as well. There was a subsequent matplotlib plotting interpolation after the original interpolation from points into an image, now ``'image_interp'`` controls the first interpolation (the plotting interpolation can be set afterward using ``im.set_interpolation``) (:gh:`10617` by `Alex Rockhill`_)
Comment thread
alexrockhill marked this conversation as resolved.
Outdated
2 changes: 1 addition & 1 deletion examples/preprocessing/eeg_bridging.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@

raw = raw_data[2].copy()

# pick two channels to simulate being bridged
# pick two channels to simulate a bridge
idx0, idx1 = 9, 10
ch0, ch1 = raw.ch_names[idx0], raw.ch_names[idx1]
bridged_idx_simulated = [(idx0, idx1)]
Expand Down
8 changes: 4 additions & 4 deletions mne/cov.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

import numpy as np

from .defaults import _EXTRAPOLATE_DEFAULT, _BORDER_DEFAULT, DEFAULTS
from .defaults import (_INTERPOLATION_DEFAULT, _EXTRAPOLATE_DEFAULT,
_BORDER_DEFAULT, DEFAULTS)
from .io.write import start_and_end_file
from .io.proj import (make_projector, _proj_equal, activate_proj,
_check_projs, _needs_eeg_average_ref_proj,
Expand Down Expand Up @@ -257,10 +258,9 @@ def plot_topomap(self, info, ch_type=None, vmin=None,
size=1, cbar_fmt="%3.1f",
proj=False, show=True, show_names=False, title=None,
mask=None, mask_params=None, outlines='head',
contours=6, image_interp='bilinear',
contours=6, image_interp=_INTERPOLATION_DEFAULT,
axes=None, extrapolate=_EXTRAPOLATE_DEFAULT, sphere=None,
border=_BORDER_DEFAULT,
noise_cov=None, verbose=None):
border=_BORDER_DEFAULT, noise_cov=None, verbose=None):
"""Plot a topomap of the covariance diagonal.

Parameters
Expand Down
13 changes: 5 additions & 8 deletions mne/decoding/csp.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .base import BaseEstimator
from .mixin import TransformerMixin
from ..cov import _regularized_covariance
from ..defaults import _INTERPOLATION_DEFAULT
from ..fixes import pinv
from ..utils import fill_doc, _check_option, _validate_type, copy_doc

Expand Down Expand Up @@ -242,7 +243,7 @@ def plot_patterns(self, info, components=None, ch_type=None,
size=1, cbar_fmt='%3.1f', name_format='CSP%01d',
show=True, show_names=False, title=None, mask=None,
mask_params=None, outlines='head', contours=6,
image_interp='bilinear', average=None,
image_interp=_INTERPOLATION_DEFAULT, average=None,
sphere=None):
"""Plot topographic patterns of components.

Expand Down Expand Up @@ -321,9 +322,7 @@ def plot_patterns(self, info, components=None, ch_type=None,
suitable values for the contour thresholds (may sometimes be
inaccurate, use array for accuracy). If an array, the values
represent the levels for the contours. Defaults to 6.
image_interp : str
The image interpolation to be used.
All matplotlib options are accepted.
%(image_interp_topomap)s
average : float | None
The time window around a given time to be used for averaging
(seconds). For example, 0.01 would translate into window that
Expand Down Expand Up @@ -364,7 +363,7 @@ def plot_filters(self, info, components=None, ch_type=None,
size=1, cbar_fmt='%3.1f', name_format='CSP%01d',
show=True, show_names=False, title=None, mask=None,
mask_params=None, outlines='head', contours=6,
image_interp='bilinear', average=None):
image_interp=_INTERPOLATION_DEFAULT, average=None):
"""Plot topographic filters of components.

The filters are used to extract discriminant neural sources from
Expand Down Expand Up @@ -449,9 +448,7 @@ def plot_filters(self, info, components=None, ch_type=None,
suitable values for the contour thresholds (may sometimes be
inaccurate, use array for accuracy). If an array, the values
represent the levels for the contours. Defaults to 6.
image_interp : str
The image interpolation to be used.
All matplotlib options are accepted.
%(image_interp_topomap)s
average : float | None
The time window around a given time to be used for averaging
(seconds). For example, 0.01 would translate into window that
Expand Down
1 change: 1 addition & 0 deletions mne/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,5 @@ def _handle_default(k, v=None):

HEAD_SIZE_DEFAULT = 0.095 # in [m]
_BORDER_DEFAULT = 'mean'
_INTERPOLATION_DEFAULT = 'cubic'
_EXTRAPOLATE_DEFAULT = 'auto'
20 changes: 12 additions & 8 deletions mne/evoked.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
from .channels.channels import (UpdateChannelsMixin,
SetChannelsMixin, InterpolationMixin)
from .channels.layout import _merge_ch_data, _pair_grad_sensors
from .defaults import _EXTRAPOLATE_DEFAULT, _BORDER_DEFAULT
from .defaults import (_INTERPOLATION_DEFAULT, _EXTRAPOLATE_DEFAULT,
_BORDER_DEFAULT)
from .filter import detrend, FilterMixin, _check_fun
from .utils import (check_fname, logger, verbose, _time_mask, warn, sizeof_fmt,
SizeMixin, copy_function_doc_to_method_doc, _validate_type,
Expand Down Expand Up @@ -484,8 +485,9 @@ def plot_topomap(self, times="auto", ch_type=None, vmin=None,
time_unit='s', time_format=None,
proj=False, show=True, show_names=False, title=None,
mask=None, mask_params=None, outlines='head',
contours=6, image_interp='bilinear', average=None,
axes=None, extrapolate=_EXTRAPOLATE_DEFAULT, sphere=None,
contours=6, image_interp=_INTERPOLATION_DEFAULT,
average=None, axes=None,
extrapolate=_EXTRAPOLATE_DEFAULT, sphere=None,
border=_BORDER_DEFAULT, nrows=1, ncols='auto'):
return plot_evoked_topomap(
self, times=times, ch_type=ch_type, vmin=vmin,
Expand All @@ -495,8 +497,8 @@ def plot_topomap(self, times="auto", ch_type=None, vmin=None,
time_format=time_format, proj=proj, show=show,
show_names=show_names, title=title, mask=mask,
mask_params=mask_params, outlines=outlines, contours=contours,
image_interp=image_interp, average=average,
axes=axes, extrapolate=extrapolate, sphere=sphere, border=border,
image_interp=image_interp, average=average, axes=axes,
extrapolate=extrapolate, sphere=sphere, border=border,
nrows=nrows, ncols=ncols)

@copy_function_doc_to_method_doc(plot_evoked_field)
Expand Down Expand Up @@ -526,8 +528,8 @@ def plot_joint(self, times="peaks", title='', picks=None,
@fill_doc
def animate_topomap(self, ch_type=None, times=None, frame_rate=None,
butterfly=False, blit=True, show=True, time_unit='s',
sphere=None, *, extrapolate=_EXTRAPOLATE_DEFAULT,
verbose=None):
sphere=None, *, image_interp=_INTERPOLATION_DEFAULT,
extrapolate=_EXTRAPOLATE_DEFAULT, verbose=None):
"""Make animation of evoked data as topomap timeseries.

The animation can be paused/resumed with left mouse button.
Expand Down Expand Up @@ -564,6 +566,7 @@ def animate_topomap(self, ch_type=None, times=None, frame_rate=None,

.. versionadded:: 0.16
%(sphere_topomap_auto)s
%(image_interp_topomap)s
%(extrapolate_topomap)s

.. versionadded:: 0.22
Expand All @@ -583,7 +586,8 @@ def animate_topomap(self, ch_type=None, times=None, frame_rate=None,
return _topomap_animation(
self, ch_type=ch_type, times=times, frame_rate=frame_rate,
butterfly=butterfly, blit=blit, show=show, time_unit=time_unit,
sphere=sphere, extrapolate=extrapolate, verbose=verbose)
sphere=sphere, image_interp=image_interp,
extrapolate=extrapolate, verbose=verbose)

def as_type(self, ch_type='grad', mode='fast'):
"""Compute virtual evoked using interpolated fields.
Expand Down
18 changes: 11 additions & 7 deletions mne/io/proj.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
from .tree import dir_tree_find
from .write import (write_int, write_float, write_string, write_name_list,
write_float_matrix, end_block, start_block)
from ..defaults import _BORDER_DEFAULT, _EXTRAPOLATE_DEFAULT
from ..defaults import (_INTERPOLATION_DEFAULT, _BORDER_DEFAULT,
_EXTRAPOLATE_DEFAULT)
from ..utils import logger, verbose, warn, fill_doc, _validate_type


Expand Down Expand Up @@ -72,7 +73,8 @@ def __deepcopy__(self, memodict):
@fill_doc
def plot_topomap(self, info, cmap=None, sensors=True,
colorbar=False, res=64, size=1, show=True,
outlines='head', contours=6, image_interp='bilinear',
outlines='head', contours=6,
image_interp=_INTERPOLATION_DEFAULT,
axes=None, vlim=(None, None), sphere=None,
border=_BORDER_DEFAULT):
"""Plot topographic maps of SSP projections.
Expand All @@ -94,10 +96,11 @@ def plot_topomap(self, info, cmap=None, sensors=True,
.. versionadded:: 0.15.0
""" # noqa: E501
from ..viz.topomap import plot_projs_topomap
return plot_projs_topomap(self, info, cmap, sensors, colorbar,
res, size, show, outlines,
contours, image_interp, axes, vlim,
sphere=sphere, border=border)
return plot_projs_topomap(
self, info, cmap, sensors, colorbar=colorbar, res=res, size=size,
show=show, outlines=outlines, contours=contours,
image_interp=image_interp, axes=axes, vlim=vlim,
sphere=sphere, border=border)


class ProjMixin(object):
Expand Down Expand Up @@ -288,7 +291,7 @@ def del_proj(self, idx='all'):
def plot_projs_topomap(self, ch_type=None, cmap=None,
sensors=True, colorbar=False, res=64, size=1,
show=True, outlines='head', contours=6,
image_interp='bilinear', axes=None,
image_interp=_INTERPOLATION_DEFAULT, axes=None,
vlim=(None, None), sphere=None,
extrapolate=_EXTRAPOLATE_DEFAULT,
border=_BORDER_DEFAULT):
Expand All @@ -303,6 +306,7 @@ def plot_projs_topomap(self, ch_type=None, cmap=None,
ch_types is provided, it will return multiple figures.
%(proj_topomap_kwargs)s
%(sphere_topomap_auto)s
%(image_interp_topomap)s
%(extrapolate_topomap)s

.. versionadded:: 0.20
Expand Down
9 changes: 5 additions & 4 deletions mne/preprocessing/ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from ..cov import compute_whitener
from .. import Covariance, Evoked
from ..defaults import _INTERPOLATION_DEFAULT
from ..io.pick import (pick_types, pick_channels, pick_info,
_picks_to_idx, _get_channel_types, _DATA_CH_TYPES_SPLIT)
from ..io.proj import make_projector
Expand Down Expand Up @@ -2027,10 +2028,10 @@ def copy(self):
def plot_components(self, picks=None, ch_type=None, res=64,
vmin=None, vmax=None, cmap='RdBu_r', sensors=True,
colorbar=False, title=None, show=True, outlines='head',
contours=6, image_interp='bilinear',
inst=None, plot_std=True, topomap_args=None,
image_args=None, psd_args=None, reject='auto',
sphere=None, verbose=None):
contours=6, image_interp=_INTERPOLATION_DEFAULT,
inst=None, plot_std=True,
topomap_args=None, image_args=None, psd_args=None,
reject='auto', sphere=None, verbose=None):
return plot_ica_components(self, picks=picks, ch_type=ch_type,
res=res, vmin=vmin,
vmax=vmax, cmap=cmap, sensors=sensors,
Expand Down
10 changes: 5 additions & 5 deletions mne/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1419,8 +1419,10 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):

docdict['image_interp_topomap'] = """
image_interp : str
The image interpolation to be used. All matplotlib options are
accepted as well as ``'voronoi'``.
The image interpolation to be used. Options are ``'cubic'`` (default)
to use :class:`scipy.interpolate.CloughTocher2DInterpolator`,
``'nearest'`` to use :class:`scipy.spatial.Voronoi` or
``'linear'`` to use :class:`scipy.interpolate.LinearNDInterpolator`.
"""

docdict['include_tmax'] = """
Expand Down Expand Up @@ -2355,9 +2357,7 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
values for the contour thresholds (may sometimes be inaccurate, use
array for accuracy). If an array, the values represent the levels for
the contours. Defaults to 6.
image_interp : str
The image interpolation to be used. All matplotlib options are
accepted.
""" + docdict['image_interp_topomap'] + """
axes : instance of Axes | list | None
The axes to plot to. If list, the list must be a list of Axes of
the same length as the number of projectors. If instance of Axes,
Expand Down
8 changes: 4 additions & 4 deletions mne/viz/tests/test_ica.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@ def test_plot_ica_components():
ica.fit(raw, picks=ica_picks)

for components in [0, [0], [0, 1], [0, 1] * 2, None]:
ica.plot_components(components, image_interp='bilinear',
ica.plot_components(components, image_interp='cubic',
colorbar=True, **fast_test)
plt.close('all')

# test interactive mode (passing 'inst' arg)
with catch_logging() as log:
ica.plot_components([0, 1], image_interp='bilinear', inst=raw, res=16,
ica.plot_components([0, 1], image_interp='cubic', inst=raw, res=16,
verbose='debug', ch_type='grad')
log = log.getvalue()
assert 'grad data' in log
assert 'Interpolation mode local to mean' in log
assert 'extrapolation mode local to mean' in log
fig = plt.gcf()

# test title click
Expand Down Expand Up @@ -144,7 +144,7 @@ def test_plot_ica_properties():
ica.plot_properties(raw, picks=0, verbose='debug', **topoargs)
log = log.getvalue()
assert raw.ch_names[0] == 'MEG 0113'
assert 'Interpolation mode local to mean' in log, log
assert 'extrapolation mode local to mean' in log, log
ica.plot_properties(epochs, picks=1, dB=False, plot_std=1.5, **topoargs)
fig = ica.plot_properties(epochs, picks=1, image_args={'sigma': 1.5},
topomap_args={'res': 4, 'colorbar': True},
Expand Down
7 changes: 4 additions & 3 deletions mne/viz/tests/test_topomap.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,14 @@ def test_plot_topomap_animation(capsys):
# evoked
evoked = read_evokeds(evoked_fname, 'Left Auditory',
baseline=(None, 0))

# Test animation
_, anim = evoked.animate_topomap(ch_type='grad', times=[0, 0.1],
butterfly=False, time_unit='s',
verbose='debug')
anim._func(1) # _animate has to be tested separately on 'Agg' backend.
out, _ = capsys.readouterr()
assert 'Interpolation mode local to 0' in out
assert 'extrapolation mode local to 0' in out
plt.close('all')


Expand All @@ -168,7 +169,7 @@ def test_plot_topomap_animation_nirs(fnirs_evoked, capsys):
fig, anim = fnirs_evoked.animate_topomap(ch_type='hbo', verbose='debug')
anim._func(1) # _animate has to be tested separately on 'Agg' backend.
out, _ = capsys.readouterr()
assert 'Interpolation mode head to 0' in out
assert 'extrapolation mode head to 0' in out
assert len(fig.axes) == 2
plt.close('all')

Expand Down Expand Up @@ -302,7 +303,7 @@ def proc_names(x):
with pytest.raises(TypeError, match='number of seconds.* got type'):
plt_topomap(times, ch_type='eeg', average='x')

p = plt_topomap(times, ch_type='grad', image_interp='bilinear',
p = plt_topomap(times, ch_type='grad', image_interp='cubic',
show_names=lambda x: x.replace('MEG', ''))
subplot = [x for x in p.get_children() if 'Subplot' in str(type(x))]
assert len(subplot) >= 1, [type(x) for x in p.get_children()]
Expand Down
Loading