@@ -184,7 +184,7 @@ def _plot_topo(info, times, show_func, click_func=None, layout=None,
184
184
layout .pos [:, :2 ] /= layout .pos [:, :2 ].max (0 )
185
185
186
186
# prepare callbacks
187
- tmin , tmax = times [[ 0 , - 1 ] ]
187
+ tmin , tmax = times [0 ], times [ - 1 ]
188
188
click_func = show_func if click_func is None else click_func
189
189
on_pick = partial (click_func , tmin = tmin , tmax = tmax , vmin = vmin ,
190
190
vmax = vmax , ylim = ylim , x_label = x_label ,
@@ -342,13 +342,13 @@ def _plot_timeseries(ax, ch_idx, tmin, tmax, vmin, vmax, ylim, data, color,
342
342
import matplotlib .pyplot as plt
343
343
from matplotlib .colors import colorConverter
344
344
picker_flag = False
345
- for data_ , color_ in zip (data , color ):
345
+ for data_ , color_ , times_ in zip (data , color , times ):
346
346
if not picker_flag :
347
347
# use large tol for picker so we can click anywhere in the axes
348
- ax .plot (times , data_ [ch_idx ], color = color_ , picker = 1e9 )
348
+ ax .plot (times_ , data_ [ch_idx ], color = color_ , picker = 1e9 )
349
349
picker_flag = True
350
350
else :
351
- ax .plot (times , data_ [ch_idx ], color = color_ )
351
+ ax .plot (times_ , data_ [ch_idx ], color = color_ )
352
352
353
353
if x_label is not None :
354
354
ax .set (xlabel = x_label )
@@ -361,17 +361,26 @@ def _plot_timeseries(ax, ch_idx, tmin, tmax, vmin, vmax, ylim, data, color,
361
361
362
362
def _format_coord (x , y , labels , ax ):
363
363
"""Create status string based on cursor coordinates."""
364
- idx = np .abs (times - x ).argmin ()
364
+ # find indices for datasets near cursor (if any)
365
+ tdiffs = [np .abs (tvec - x ).min () for tvec in times ]
366
+ nearby = [k for k , tdiff in enumerate (tdiffs ) if
367
+ tdiff < (tmax - tmin ) / 100 ]
368
+ timestr = '%6.3f s: ' % x
369
+ if not nearby :
370
+ return '%s Nothing here' % timestr
371
+ nearby_data = [(data [n ], labels [n ], times [n ]) for n in nearby ]
365
372
ylabel = ax .get_ylabel ()
366
373
unit = (ylabel [ylabel .find ('(' ) + 1 :ylabel .find (')' )]
367
374
if '(' in ylabel and ')' in ylabel else '' )
368
- labels = ['' ] * len (data ) if labels is None else labels
375
+ labels = ['' ] * len (nearby_data ) if labels is None else labels
369
376
# try to estimate whether to truncate condition labels
370
377
slen = 10 + sum ([12 + len (unit ) + len (label ) for label in labels ])
371
378
bar_width = (ax .figure .get_size_inches () * ax .figure .dpi )[0 ] / 5.5
379
+ # show labels and y values for datasets near cursor
372
380
trunc_labels = bar_width < slen
373
- s = '%6.3f s: ' % times [idx ]
374
- for data_ , label in zip (data , labels ):
381
+ s = timestr
382
+ for data_ , label , tvec in nearby_data :
383
+ idx = np .abs (tvec - x ).argmin ()
375
384
s += '%7.2f %s' % (data_ [ch_idx , idx ], unit )
376
385
if trunc_labels :
377
386
label = (label if len (label ) <= 10 else
@@ -437,16 +446,16 @@ def _plot_timeseries_unified(bn, ch_idx, tmin, tmax, vmin, vmax, ylim, data,
437
446
"""Show multiple time series on topo using a single axes."""
438
447
import matplotlib .pyplot as plt
439
448
if not (ylim and not any (v is None for v in ylim )):
440
- ylim = np . array ([ np .min (data ), np .max (data )])
449
+ ylim = [ min ( np .min (d ) for d in data ), max ( np .max (d ) for d in data )]
441
450
# Translation and scale parameters to take data->under_ax normalized coords
442
451
_compute_scalings (bn , (tmin , tmax ), ylim )
443
452
pos = bn .pos
444
453
data_lines = bn .data_lines
445
454
ax = bn .ax
446
455
# XXX These calls could probably be made faster by using collections
447
- for data_ , color_ in zip (data , color ):
456
+ for data_ , color_ , times_ in zip (data , color , times ):
448
457
data_lines .append (ax .plot (
449
- bn .x_t + bn .x_s * times , bn .y_t + bn .y_s * data_ [ch_idx ],
458
+ bn .x_t + bn .x_s * times_ , bn .y_t + bn .y_s * data_ [ch_idx ],
450
459
linewidth = 0.5 , color = color_ , clip_on = True , clip_box = pos )[0 ])
451
460
if vline :
452
461
vline = np .array (vline ) * bn .x_s + bn .x_t
@@ -631,10 +640,6 @@ def _plot_evoked_topo(evoked, layout=None, layout_scale=0.945, color=None,
631
640
else :
632
641
color = cycle ([color ])
633
642
634
- times = evoked [0 ].times
635
- if not all ((e .times == times ).all () for e in evoked ):
636
- raise ValueError ('All evoked.times must be the same' )
637
-
638
643
noise_cov = _check_cov (noise_cov , evoked [0 ].info )
639
644
if noise_cov is not None :
640
645
evoked = [whiten_evoked (e , noise_cov ) for e in evoked ]
@@ -712,11 +717,10 @@ def _plot_evoked_topo(evoked, layout=None, layout_scale=0.945, color=None,
712
717
y_label .append ('Amplitude (%s)' % unit )
713
718
714
719
if ylim is None :
715
- def set_ylim (x ):
716
- return np .abs (x ).max ()
717
- ylim_ = [set_ylim ([e .data [t ] for e in evoked ]) for t in picks ]
718
- ymax = np .array (ylim_ )
719
- ylim_ = (- ymax , ymax )
720
+ # find maxima over all evoked data for each channel pick
721
+ ymaxes = np .array ([max (np .abs (e .data [t ]).max () for e in evoked )
722
+ for t in picks ])
723
+ ylim_ = (- ymaxes , ymaxes )
720
724
elif isinstance (ylim , dict ):
721
725
ylim_ = _handle_default ('ylim' , ylim )
722
726
ylim_ = [ylim_ [kk ] for kk in types_used ]
@@ -730,20 +734,25 @@ def set_ylim(x):
730
734
731
735
data = [e .data for e in evoked ]
732
736
comments = [e .comment for e in evoked ]
737
+ times = [e .times for e in evoked ]
738
+
733
739
show_func = partial (_plot_timeseries_unified , data = data , color = color ,
734
740
times = times , vline = vline , hline = hline ,
735
741
hvline_color = font_color )
736
742
click_func = partial (_plot_timeseries , data = data , color = color , times = times ,
737
743
vline = vline , hline = hline , hvline_color = font_color ,
738
744
labels = comments )
739
745
740
- fig = _plot_topo (info = info , times = times , show_func = show_func ,
741
- click_func = click_func , layout = layout , colorbar = False ,
742
- ylim = ylim_ , cmap = None , layout_scale = layout_scale ,
743
- border = border , fig_facecolor = fig_facecolor ,
744
- font_color = font_color , axis_facecolor = axis_facecolor ,
745
- title = title , x_label = 'Time (s)' , y_label = y_label ,
746
- unified = True , axes = axes )
746
+ time_min = min ([t [0 ] for t in times ])
747
+ time_max = max ([t [- 1 ] for t in times ])
748
+ fig = _plot_topo (info = info , times = [time_min , time_max ],
749
+ show_func = show_func , click_func = click_func , layout = layout ,
750
+ colorbar = False , ylim = ylim_ , cmap = None ,
751
+ layout_scale = layout_scale , border = border ,
752
+ fig_facecolor = fig_facecolor , font_color = font_color ,
753
+ axis_facecolor = axis_facecolor , title = title ,
754
+ x_label = 'Time (s)' , y_label = y_label , unified = True ,
755
+ axes = axes )
747
756
748
757
add_background_image (fig , fig_background )
749
758
0 commit comments