Skip to content

Commit 99594f9

Browse files
authored
Merge pull request #182 from christianbrodbeck/data-layers
FIX: showing multiple data layers
2 parents 075de95 + bcba87e commit 99594f9

File tree

2 files changed

+73
-15
lines changed

2 files changed

+73
-15
lines changed

surfer/tests/test_viz.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,27 @@ def time_label(t):
219219
assert_equal(brain.data_dict['lh']['time_idx'], 2)
220220
# viewer = TimeViewer(brain)
221221

222+
# multiple data layers
223+
assert_raises(ValueError, brain.add_data, data, vertices=vertices,
224+
time=time[:-1])
222225
brain.add_data(data, colormap=colormap, vertices=vertices,
223226
smoothing_steps=10, time=time, time_label=time_label,
224-
initial_time=.09, remove_existing=True)
227+
initial_time=.09)
225228
assert_equal(brain.data_dict['lh']['time_idx'], 1)
229+
data_dicts = brain._data_dicts['lh']
230+
assert_equal(len(data_dicts), 2)
231+
assert_equal(data_dicts[0]['time_idx'], 1)
232+
assert_equal(data_dicts[1]['time_idx'], 1)
233+
234+
# shift time in both layers
235+
brain.set_data_time_index(0)
236+
assert_equal(data_dicts[0]['time_idx'], 0)
237+
assert_equal(data_dicts[1]['time_idx'], 0)
238+
239+
# remove all layers
240+
brain.remove_data()
241+
assert_equal(brain._data_dicts['lh'], [])
242+
226243
brain.close()
227244

228245

surfer/viz.py

+55-14
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,20 @@ def __init__(self, subject_id, hemi, surf, title=None,
500500
self.contour_list = []
501501
self.morphometry_list = []
502502
self.annot_list = []
503-
self.data_dict = dict(lh=None, rh=None)
503+
self._data_dicts = dict(lh=[], rh=[])
504504
# note that texts gets treated differently
505505
self.texts_dict = dict()
506+
self._times = None
506507
self.n_times = None
507508

509+
@property
510+
def data_dict(self):
511+
"""For backwards compatibility"""
512+
lh_list = self._data_dicts['lh']
513+
rh_list = self._data_dicts['rh']
514+
return dict(lh=lh_list[-1] if lh_list else None,
515+
rh=rh_list[-1] if rh_list else None)
516+
508517
###########################################################################
509518
# HELPERS
510519
def _toggle_render(self, state, views=None):
@@ -1052,20 +1061,38 @@ def add_data(self, array, min=None, max=None, thresh=None,
10521061
transparent=False, time=0, time_idx=0,
10531062
vertices=vertices, smooth_mat=smooth_mat)
10541063

1064+
# clean up existing data
1065+
if remove_existing:
1066+
self.remove_data(hemi)
1067+
10551068
# Create time array and add label if 2D
10561069
if array.ndim == 2:
1070+
# check time array
10571071
if time is None:
10581072
time = np.arange(array.shape[1])
1059-
self._times = time
1060-
self.n_times = array.shape[1]
1061-
if not self.n_times == len(time):
1062-
raise ValueError('time is not the same length as '
1063-
'array.shape[1]')
1073+
else:
1074+
time = np.asarray(time)
1075+
if time.shape != (array.shape[1],):
1076+
raise ValueError('time has shape %s, but need shape %s '
1077+
'(array.shape[1])' %
1078+
(time.shape, (array.shape[1],)))
1079+
1080+
if self.n_times is None:
1081+
self.n_times = len(time)
1082+
self._times = time
1083+
elif len(time) != self.n_times:
1084+
raise ValueError("New n_times is different from previous "
1085+
"n_times")
1086+
elif not np.array_equal(time, self._times):
1087+
raise ValueError("Not all time values are consistent with "
1088+
"previously set times.")
1089+
10641090
# initial time
10651091
if initial_time is None:
10661092
initial_time_index = None
10671093
else:
10681094
initial_time_index = self.index_for_time(initial_time)
1095+
10691096
# time label
10701097
if isinstance(time_label, string_types):
10711098
time_label_fmt = time_label
@@ -1077,8 +1104,6 @@ def time_label(x):
10771104
data["time_idx"] = 0
10781105
y_txt = 0.05 + 0.05 * bool(colorbar)
10791106
else:
1080-
self._times = None
1081-
self.n_times = None
10821107
initial_time_index = None
10831108

10841109
surfs = []
@@ -1103,10 +1128,7 @@ def time_label(x):
11031128
data['colorbars'] = bars
11041129
data['orig_ctable'] = ct
11051130

1106-
if remove_existing and self.data_dict[hemi] is not None:
1107-
for surf in self.data_dict[hemi]['surfaces']:
1108-
surf.parent.parent.remove()
1109-
self.data_dict[hemi] = data
1131+
self._data_dicts[hemi].append(data)
11101132

11111133
if initial_time_index is not None:
11121134
self.set_data_time_index(initial_time_index)
@@ -1340,6 +1362,26 @@ def _to_borders(self, label, hemi, borders, restrict_idx=None):
13401362
show[keep_idx] = 1
13411363
label *= show
13421364

1365+
def remove_data(self, hemi=None):
1366+
"""Remove data shown with ``Brain.add_data()``.
1367+
1368+
Parameters
1369+
----------
1370+
hemi : str | None
1371+
Hemisphere from which to remove data (default is all shown
1372+
hemispheres).
1373+
"""
1374+
hemis = self._check_hemis(hemi)
1375+
for hemi in hemis:
1376+
for data in self._data_dicts[hemi]:
1377+
for surf in data['surfaces']:
1378+
surf.parent.parent.remove()
1379+
self._data_dicts[hemi] = []
1380+
1381+
# if no data is left, reset time properties
1382+
if not self._data_dicts['lh'] and not self._data_dicts['rh']:
1383+
self.n_times = self._times = None
1384+
13431385
def remove_labels(self, labels=None, hemi=None):
13441386
"""Remove one or more previously added labels from the image.
13451387
@@ -1797,8 +1839,7 @@ def set_data_time_index(self, time_idx, interpolation='quadratic'):
17971839

17981840
views = self._toggle_render(False)
17991841
for hemi in ['lh', 'rh']:
1800-
data = self.data_dict[hemi]
1801-
if data is not None:
1842+
for data in self._data_dicts[hemi]:
18021843
# interpolation
18031844
if isinstance(time_idx, float):
18041845
times = np.arange(self.n_times)

0 commit comments

Comments
 (0)