Skip to content

Commit 755bf18

Browse files
committed
Update RasterWidget
1 parent 2eaa282 commit 755bf18

1 file changed

Lines changed: 55 additions & 50 deletions

File tree

src/spikeinterface/widgets/rasters.py

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,19 @@ def _update_plot(self, change=None):
269269
self.figure.canvas.flush_events()
270270

271271

272-
class RasterWidget(BaseWidget):
272+
import numpy as np
273+
274+
275+
class RasterWidget(BaseRasterWidget):
273276
"""
274277
Plots spike train rasters.
275278
276279
Parameters
277280
----------
278-
sorting : SortingExtractor
279-
The sorting extractor object
281+
sorting : SortingExtractor | None, default: None
282+
A sorting object
283+
sorting_analyzer : SortingAnalyzer | None, default: None
284+
A sorting analyzer object
280285
segment_index : None or int
281286
The segment index.
282287
unit_ids : list
@@ -288,64 +293,64 @@ class RasterWidget(BaseWidget):
288293
"""
289294

290295
def __init__(
291-
self, sorting, segment_index=None, unit_ids=None, time_range=None, color="k", backend=None, **backend_kwargs
296+
self,
297+
sorting=None,
298+
sorting_analyzer=None,
299+
segment_index=None,
300+
unit_ids=None,
301+
time_range=None,
302+
color="k",
303+
backend=None,
304+
**backend_kwargs,
292305
):
306+
if sorting is None and sorting_analyzer is None:
307+
raise Exception("Must supply either a sorting or a sorting_analyzer")
308+
if sorting is not None and sorting_analyzer is not None:
309+
raise Exception("Should supply either a sorting or a sorting_analyzer, not both")
310+
if sorting_analyzer is not None:
311+
sorting = sorting_analyzer.sorting
312+
293313
sorting = self.ensure_sorting(sorting)
294314

295315
if segment_index is None:
296316
if sorting.get_num_segments() != 1:
297317
raise ValueError("You must provide segment_index=...")
298318
segment_index = 0
299319

300-
if time_range is None:
301-
frame_range = [0, sorting.to_spike_vector()[-1]["sample_index"]]
302-
time_range = [f / sorting.sampling_frequency for f in frame_range]
303-
else:
320+
if unit_ids is None:
321+
unit_ids = sorting.unit_ids
322+
323+
all_spiketrains = {
324+
unit_id: sorting.get_unit_spike_train(unit_id, segment_index=0, return_times=True) for unit_id in unit_ids
325+
}
326+
327+
if time_range is not None:
304328
assert len(time_range) == 2, "'time_range' should be a list with start and end time in seconds"
305-
frame_range = [int(t * sorting.sampling_frequency) for t in time_range]
329+
for unit_id in unit_ids:
330+
unit_st = all_spiketrains[unit_id]
331+
all_spiketrains[unit_id] = unit_st[(time_range[0] < unit_st) & (unit_st < time_range[1])]
306332

307-
plot_data = dict(
308-
sorting=sorting,
309-
segment_index=segment_index,
310-
unit_ids=unit_ids,
311-
color=color,
312-
frame_range=frame_range,
313-
time_range=time_range,
314-
)
315-
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
333+
raster_locations = {
334+
unit_id: unit_index * np.ones(len(all_spiketrains[unit_id])) for unit_index, unit_id in enumerate(unit_ids)
335+
}
316336

317-
def plot_matplotlib(self, data_plot, **backend_kwargs):
318-
import matplotlib.pyplot as plt
319-
from .utils_matplotlib import make_mpl_figure
337+
unit_indices = list(range(len(unit_ids)))
320338

321-
dp = to_attr(data_plot)
322-
sorting = dp.sorting
339+
if color is None:
340+
color = "black"
323341

324-
self.figure, self.axes, self.ax = make_mpl_figure(**backend_kwargs)
342+
unit_colors = {unit_id: color for unit_id in unit_ids}
343+
y_ticks = {"ticks": unit_indices, "labels": unit_ids}
344+
345+
plot_data = dict(
346+
spike_train_data=all_spiketrains,
347+
y_axis_data=raster_locations,
348+
x_lim=time_range,
349+
y_label="Unit id",
350+
unit_ids=unit_ids,
351+
unit_colors=unit_colors,
352+
plot_histograms=None,
353+
y_ticks=y_ticks,
354+
)
325355

326-
units_ids = dp.unit_ids
327-
if units_ids is None:
328-
units_ids = sorting.unit_ids
329-
330-
with plt.rc_context({"axes.edgecolor": "gray"}):
331-
for unit_index, unit_id in enumerate(units_ids):
332-
spiketrain = sorting.get_unit_spike_train(
333-
unit_id,
334-
start_frame=dp.frame_range[0],
335-
end_frame=dp.frame_range[1],
336-
segment_index=dp.segment_index,
337-
)
338-
spiketimes = spiketrain / float(sorting.sampling_frequency)
339-
self.ax.plot(
340-
spiketimes,
341-
unit_index * np.ones_like(spiketimes),
342-
marker="|",
343-
mew=1,
344-
markersize=3,
345-
ls="",
346-
color=dp.color,
347-
)
348-
self.ax.set_yticks(np.arange(len(units_ids)))
349-
self.ax.set_yticklabels(units_ids)
350-
self.ax.set_xlim(*dp.time_range)
351-
self.ax.set_xlabel("time (s)")
356+
BaseRasterWidget.__init__(self, **plot_data, backend=backend, **backend_kwargs)

0 commit comments

Comments
 (0)