Skip to content

Commit 4577b5f

Browse files
committed
MRG, FIX: Fix tick labeling (#7811)
* FIX: Fix tick labeling * FIX: Add debugging
1 parent 76fc838 commit 4577b5f

File tree

8 files changed

+53
-28
lines changed

8 files changed

+53
-28
lines changed

doc/changes/0.20.inc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88
- "API" for backward-incompatible changes
99

1010

11+
.. _changes_0_20_8:
12+
13+
Version 0.20.8
14+
--------------
15+
16+
Bug
17+
~~~
18+
19+
- Fix bug with :meth:`mne.io.Raw.plot` with newer matplotlib where tick labeling would raise an error by `Eric Larson`_
20+
21+
1122
.. _changes_0_20_7:
1223

1324
Version 0.20.7

mne/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# Dev branch marker is: 'X.Y.devN' where N is an integer.
1717
#
1818

19-
__version__ = '0.20.7'
19+
__version__ = '0.20.8'
2020

2121
# have to import verbose first since it's needed by many things
2222
from .utils import (set_log_level, set_log_file, verbose, set_config,

mne/conftest.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def pytest_configure(config):
8787
ignore:.*pandas\.util\.testing is deprecated.*:
8888
ignore:.*tostring.*is deprecated.*:DeprecationWarning
8989
always:.*get_data.* is deprecated in favor of.*:DeprecationWarning
90+
ignore:.*Passing the dash.*:
9091
""" # noqa: E501
9192
for warning_line in warning_lines.split('\n'):
9293
warning_line = warning_line.strip()
@@ -115,13 +116,19 @@ def matplotlib_config():
115116
"""Configure matplotlib for viz tests."""
116117
import matplotlib
117118
from matplotlib import cbook
118-
# "force" should not really be necessary but should not hurt
119-
kwargs = dict()
119+
# Allow for easy interactive debugging with a call like:
120+
#
121+
# $ MNE_MPL_TESTING_BACKEND=Qt5Agg pytest mne/viz/tests/test_raw.py -k annotation -x --pdb # noqa: E501
122+
#
123+
try:
124+
want = os.environ['MNE_MPL_TESTING_BACKEND']
125+
except KeyError:
126+
want = 'agg' # don't pop up windows
120127
with warnings.catch_warnings(record=True): # ignore warning
121128
warnings.filterwarnings('ignore')
122-
matplotlib.use('agg', force=True, **kwargs) # don't pop up windows
129+
matplotlib.use(want, force=True)
123130
import matplotlib.pyplot as plt
124-
assert plt.get_backend() == 'agg'
131+
assert plt.get_backend() == want
125132
# overwrite some params that can horribly slow down tests that
126133
# users might have changed locally (but should not otherwise affect
127134
# functionality)

mne/viz/_3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3192,7 +3192,7 @@ def plot_brain_colorbar(ax, clim, colormap='auto', transparent=True,
31923192
colormap, lims = _linearize_map(mapdata)
31933193
del mapdata
31943194
norm = Normalize(vmin=lims[0], vmax=lims[2])
3195-
cbar = ColorbarBase(ax, colormap, norm=norm, ticks=ticks,
3195+
cbar = ColorbarBase(ax, cmap=colormap, norm=norm, ticks=ticks,
31963196
label=label, orientation=orientation)
31973197
# make the colorbar background match the brain color
31983198
cbar.patch.set(facecolor=bgcolor)

mne/viz/epochs.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ def plot_epochs(epochs, picks=None, scalings=None, n_epochs=20, n_channels=20,
854854
projs = epochs.info['projs']
855855
noise_cov = _check_cov(noise_cov, epochs.info)
856856

857-
params = dict(epochs=epochs, info=epochs.info.copy(), t_start=0.,
857+
params = dict(epochs=epochs, info=epochs.info.copy(), t_start=0,
858858
bad_color=(0.8, 0.8, 0.8), histogram=None, decim=decim,
859859
data_picks=data_picks, noise_cov=noise_cov,
860860
use_noise_cov=noise_cov is not None,
@@ -1092,10 +1092,10 @@ def _prepare_mne_browse_epochs(params, projs, n_channels, n_epochs, scalings,
10921092
ax.set_yticks(offsets)
10931093
ax.set_ylim(ylim)
10941094
ticks = epoch_times + 0.5 * n_times
1095-
ax.set_xticks(ticks)
1096-
ax2.set_xticks(ticks[:n_epochs])
1095+
for ax_ in (ax, ax2):
1096+
ax_.set_xticks(ticks[:n_epochs])
10971097
labels = list(range(0, len(ticks))) # epoch numbers
1098-
ax.set_xticklabels(labels)
1098+
ax.set_xticklabels(labels[:n_epochs])
10991099
xlim = epoch_times[-1] + len(orig_epoch_times)
11001100
ax_hscroll.set_xlim(0, xlim)
11011101
vertline_t = ax_hscroll.text(0, 1, '', color='y', va='bottom', ha='right')
@@ -1252,13 +1252,14 @@ def _plot_traces(params):
12521252

12531253
n_times = len(epochs.times)
12541254
tick_list = list()
1255-
start_idx = int(params['t_start'] / n_times)
1255+
start_idx = params['t_start'] // n_times
12561256
end = params['t_start'] + params['duration']
1257-
end_idx = int(end / n_times)
1258-
xlabels = params['labels'][start_idx:]
1259-
event_ids = params['epochs'].events[:, 2]
1260-
params['ax2'].set_xticklabels(event_ids[start_idx:])
1257+
end_idx = end // n_times
1258+
xlabels = params['labels'][start_idx:end_idx]
1259+
event_ids = params['epochs'].events[start_idx:end_idx, 2]
1260+
params['ax2'].set_xticklabels(event_ids)
12611261
ax.set_xticklabels(xlabels)
1262+
del event_ids, xlabels
12621263
ylabels = ax.yaxis.get_ticklabels()
12631264
# do the plotting
12641265
for line_idx in range(n_channels):
@@ -1339,7 +1340,7 @@ def _plot_traces(params):
13391340
0, ylim + 1, ylim / (4 * max(len(chan_types_split), 1)))
13401341
offset_pos = np.arange(2, (len(chan_types_split) * 4) + 1, 4)
13411342
ax.set_yticks(ticks)
1342-
labels = [''] * 20
1343+
labels = [''] * len(ticks)
13431344
labels = [0 if idx in range(2, len(labels), 4) else label
13441345
for idx, label in enumerate(labels)]
13451346
for idx_chan, chan_type in enumerate(chan_types_split):
@@ -1356,6 +1357,7 @@ def _plot_traces(params):
13561357
labels[li] = round(label, 2)
13571358
ax.set_yticklabels(labels, fontsize=12, color='black')
13581359
else:
1360+
ax.set_yticks(params['offsets'][:len(tick_list)])
13591361
ax.set_yticklabels(tick_list, fontsize=12)
13601362
_set_ax_label_style(ax, params)
13611363

@@ -1382,7 +1384,7 @@ def _plot_update_epochs_proj(params, bools=None):
13821384
n_epochs = params['n_epochs']
13831385
params['projector'], params['whitened_ch_names'] = _setup_plot_projector(
13841386
params['info'], params['noise_cov'], True, params['use_noise_cov'])
1385-
start = int(params['t_start'] / len(epochs.times))
1387+
start = params['t_start'] // len(epochs.times)
13861388
end = start + n_epochs
13871389
if epochs.preload:
13881390
data = np.concatenate(epochs.get_data()[start:end], axis=1)
@@ -1419,6 +1421,7 @@ def _handle_picks(epochs):
14191421
def _plot_window(value, params):
14201422
"""Deal with horizontal shift of the viewport."""
14211423
max_times = len(params['times']) - params['duration']
1424+
value = int(round(value))
14221425
if value > max_times:
14231426
value = len(params['times']) - params['duration']
14241427
if value < 0:
@@ -1681,7 +1684,8 @@ def _plot_onkey(event, params):
16811684
return
16821685
n_times = len(params['epochs'].times)
16831686
ticks = params['epoch_times'] + 0.5 * n_times
1684-
params['ax2'].set_xticks(ticks[:n_epochs])
1687+
for key in ('ax', 'ax2'):
1688+
params[key].set_xticks(ticks[:n_epochs])
16851689
params['n_epochs'] = n_epochs
16861690
params['duration'] -= n_times
16871691
params['hsel_patch'].set_width(params['duration'])
@@ -1693,7 +1697,8 @@ def _plot_onkey(event, params):
16931697
if n_times * n_epochs > len(params['times']):
16941698
return
16951699
ticks = params['epoch_times'] + 0.5 * n_times
1696-
params['ax2'].set_xticks(ticks[:n_epochs])
1700+
for key in ('ax', 'ax2'):
1701+
params[key].set_xticks(ticks[:n_epochs])
16971702
params['n_epochs'] = n_epochs
16981703
if len(params['vert_lines']) > 0:
16991704
ax = params['ax']
@@ -1842,7 +1847,8 @@ def _update_channels_epochs(event, params):
18421847
n_epochs = int(np.around(params['epoch_slider'].val))
18431848
n_times = len(params['epochs'].times)
18441849
ticks = params['epoch_times'] + 0.5 * n_times
1845-
params['ax2'].set_xticks(ticks[:n_epochs])
1850+
for key in ('ax', 'ax2'):
1851+
params[key].set_xticks(ticks[:n_epochs])
18461852
params['n_epochs'] = n_epochs
18471853
params['duration'] = n_times * n_epochs
18481854
params['hsel_patch'].set_width(params['duration'])
@@ -2003,7 +2009,7 @@ def _draw_event_lines(params):
20032009
includes_tzero = False
20042010
epochs = params['epochs']
20052011
n_times = len(epochs.times)
2006-
start_idx = int(params['t_start'] / n_times)
2012+
start_idx = params['t_start'] // n_times
20072013
color = params['event_colors']
20082014
ax = params['ax']
20092015
for ev_line in params['ev_lines']:

mne/viz/raw.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ def _plot_raw_traces(params, color, bad_color, event_lines=None,
901901
params['times'][0] + params['first_time'] +
902902
params['duration'], False)
903903
if not butterfly:
904+
params['ax'].set_yticks(params['offsets'][:len(tick_list)])
904905
params['ax'].set_yticklabels(tick_list, rotation=0)
905906
_set_ax_label_style(params['ax'], params)
906907
if 'fig_selection' not in params:

mne/viz/tests/test_raw.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _annotation_helper(raw, events=False):
102102
kind='release')
103103
if mpl_good_enough:
104104
assert raw.annotations.onset[n_anns] == onset
105-
assert_allclose(raw.annotations.duration[n_anns], 1.5)
105+
assert_allclose(raw.annotations.duration[n_anns], 1.5) # 4->1.5
106106
# modify annotation from beginning
107107
_fake_click(fig, data_ax, [1., 1.], xform='data', button=1, kind='press')
108108
_fake_click(fig, data_ax, [0.5, 1.], xform='data', button=1, kind='motion')

mne/viz/utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,8 +2433,8 @@ def _setup_butterfly(params):
24332433
ylim = (5. * len(picks), 0.)
24342434
ax.set_ylim(ylim)
24352435
offset = ylim[0] / (len(picks) + 1)
2436-
ticks = np.arange(0, ylim[0], offset)
2437-
ticks = [ticks[x] if x < len(ticks) else 0 for x in range(20)]
2436+
# ensure the last is not included
2437+
ticks = np.arange(0, ylim[0] - offset / 2., offset)
24382438
ax.set_yticks(ticks)
24392439
offsets = np.zeros(len(params['types']))
24402440

@@ -2443,8 +2443,8 @@ def _setup_butterfly(params):
24432443
offsets[pick] = offset * (group_idx + 1)
24442444
params['inds'] = params['orig_inds'].copy()
24452445
params['offsets'] = offsets
2446-
ax.set_yticklabels([''] + selections, color='black', rotation=45,
2447-
va='top')
2446+
ax.set_yticklabels(
2447+
[''] + selections, color='black', rotation=45, va='top')
24482448
else:
24492449
params['inds'] = params['orig_inds'].copy()
24502450
if 'fig_selection' not in params:
@@ -2600,8 +2600,8 @@ def log_fix(tval):
26002600
axes.spines['left'].set_bounds(*ybounds)
26012601
# handle axis labels
26022602
if skip_axlabel:
2603-
axes.set_yticklabels([])
2604-
axes.set_xticklabels([])
2603+
axes.set_yticklabels([''] * len(yticks))
2604+
axes.set_xticklabels([''] * len(xticks))
26052605
else:
26062606
if unit is not None:
26072607
axes.set_ylabel(unit, rotation=90)

0 commit comments

Comments
 (0)