Skip to content

Commit 354fdce

Browse files
ruuskaspre-commit-ci[bot]larsoner
authored andcommitted
Fix evoked topomap colorbars, closes mne-tools#13050 (mne-tools#13063)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Larson <[email protected]>
1 parent 5f655b0 commit 354fdce

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

doc/changes/devel/13063.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bug in the colorbars created by :func:`mne.viz.plot_evoked_topomap` by `Santeri Ruuskanen`_.

examples/visualization/evoked_topomap.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
Plotting topographic maps of evoked data
66
========================================
77
8-
Load evoked data and plot topomaps for selected time points using multiple
9-
additional options.
8+
Load evoked data and plot topomaps for selected time points using
9+
multiple additional options.
1010
"""
1111
# Authors: Christian Brodbeck <[email protected]>
1212
# Tal Linzen <[email protected]>

mne/viz/evoked.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
_clean_names,
2828
_is_numeric,
2929
_pl,
30+
_time_mask,
3031
_to_rgb,
3132
_validate_type,
3233
fill_doc,
@@ -1988,10 +1989,18 @@ def plot_evoked_joint(
19881989
contours = topomap_args.get("contours", 6)
19891990
ch_type = ch_types.pop() # set should only contain one element
19901991
# Since the data has all the ch_types, we get the limits from the plot.
1991-
vmin, vmax = ts_ax.get_ylim()
1992+
vmin, vmax = (None, None)
19921993
norm = ch_type == "grad"
19931994
vmin = 0 if norm else vmin
1994-
vmin, vmax = _setup_vmin_vmax(evoked.data, vmin, vmax, norm)
1995+
time_idx = [
1996+
np.where(
1997+
_time_mask(evoked.times, tmin=t, tmax=None, sfreq=evoked.info["sfreq"])
1998+
)[0][0]
1999+
for t in times_sec
2000+
]
2001+
scalings = topomap_args["scalings"] if "scalings" in topomap_args else None
2002+
scaling = _handle_default("scalings", scalings)[ch_type]
2003+
vmin, vmax = _setup_vmin_vmax(evoked.data[:, time_idx] * scaling, vmin, vmax, norm)
19952004
if not isinstance(contours, list | np.ndarray):
19962005
locator, contours = _set_contour_locator(vmin, vmax, contours)
19972006
else:

mne/viz/topomap.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,22 @@ def plot_evoked_topomap(
21142114
:ref:`gridspec <matplotlib:arranging_axes>` interface to adjust the colorbar
21152115
size yourself.
21162116
2117+
The defaults for ``contours`` and ``vlim`` are handled as follows:
2118+
2119+
* When neither ``vlim`` nor a list of ``contours`` is passed, MNE sets
2120+
``vlim`` at ± the maximum absolute value of the data and then chooses
2121+
contours within those bounds.
2122+
2123+
* When ``vlim`` but not a list of ``contours`` is passed, MNE chooses
2124+
contours to be within the ``vlim``.
2125+
2126+
* When a list of ``contours`` but not ``vlim`` is passed, MNE chooses
2127+
``vlim`` to encompass the ``contours`` and the maximum absolute value of the
2128+
data.
2129+
2130+
* When both a list of ``contours`` and ``vlim`` are passed, MNE uses them
2131+
as-is.
2132+
21172133
When ``time=="interactive"``, the figure will publish and subscribe to the
21182134
following UI events:
21192135
@@ -2296,11 +2312,17 @@ def plot_evoked_topomap(
22962312
_vlim = [
22972313
_setup_vmin_vmax(data[:, i], *vlim, norm=merge_channels) for i in range(n_times)
22982314
]
2299-
_vlim = (np.min(_vlim), np.max(_vlim))
2315+
_vlim = [np.min(_vlim), np.max(_vlim)]
23002316
cmap = _setup_cmap(cmap, n_axes=n_times, norm=_vlim[0] >= 0)
23012317
# set up contours
23022318
if not isinstance(contours, list | np.ndarray):
23032319
_, contours = _set_contour_locator(*_vlim, contours)
2320+
else:
2321+
if vlim[0] is None and np.any(contours < _vlim[0]):
2322+
_vlim[0] = contours[0]
2323+
if vlim[1] is None and np.any(contours > _vlim[1]):
2324+
_vlim[1] = contours[-1]
2325+
23042326
# prepare for main loop over times
23052327
kwargs = dict(
23062328
sensors=sensors,
@@ -3348,6 +3370,7 @@ def _set_contour_locator(vmin, vmax, contours):
33483370
# correct number of bins is equal to contours + 1.
33493371
locator = ticker.MaxNLocator(nbins=contours + 1)
33503372
contours = locator.tick_values(vmin, vmax)
3373+
contours = contours[1:-1]
33513374
return locator, contours
33523375

33533376

0 commit comments

Comments
 (0)