Coder Social home page Coder Social logo

neurodatawithoutborders / nwbwidgets Goto Github PK

View Code? Open in Web Editor NEW
47.0 47.0 22.0 15.05 MB

Explore the hierarchical structure of NWB 2.0 files and visualize data with Jupyter widgets.

Home Page: https://nwb-widgets.readthedocs.io/en/latest/

License: Other

Python 99.09% Dockerfile 0.26% Jupyter Notebook 0.58% Shell 0.07%
jupyter jupyter-notebook nwb python visualization

nwbwidgets's People

Contributors

abbydichter avatar ajtritt avatar alejoe91 avatar armin12 avatar bendichter avatar bjhardcastle avatar brianhhu avatar codycbakerphd avatar d-sot avatar davclark avatar h-mayorquin avatar luiztauffer avatar magland avatar mrscheid avatar nicain avatar nilegraddis avatar oruebel avatar pre-commit-ci[bot] avatar rly avatar saksham20 avatar thewtex avatar tomdonoghue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nwbwidgets's Issues

plot_traces select specific traces

All the timeseries plotters assume you want to show traces in a continuous range, e.g. 2-10, but often you want to show traces that are in a discontinuous range, e.g. [2,4,6,7]. We need to refactor a few of these functions to support this behavior, and provide a selector type that allows multiple selection.

Where can I get sample data?

I've set up a sample Gigantum project to demo nwb-jupyter-widgets: gigantum.com/tinydav/nwb-ipy-widget-testing

Unfortunately, it won't work without data. Can you point me to where I might get YutaMouse41-150903.nwb or some other good demo file?

to_lazy_dataframe

Loading an entire hdmf DynamicTable into a pandas.DataFrame can take too long, especially if we are just doing that so we can print the table. We need a way to skip loading the large segments of data. I think the best way to do this would be to use lazy_ops, and load views to the corresponding data regions.

exported NWB file reads experimenter as bytes in pyNWB

When an NWB file is exported from MatNWB, pyNWB will read its experimenter information as bytes instead of string, causing nwbwidgets error: TypeError: sequence item 0: expected str instance, bytes found.

So, in detail, if I define an NWB in matNWB
(...'general_experimenter', 'input later'...)
or
(...'general_experimenter', {'input later'}...)

And reads it in pyNWB, print nwb.experimenter, it will show: (b'input later',)

Consequently if I run nwb2widget(nwb), I get an error message: TypeError: sequence item 0: expected str instance, bytes found

For a sample data that works in nwbwidgets, if I read it in matNWB, and run disp(nwb.general_experimenter), it will show

DataStub with properties:

    filename: '/Users/bichanwu/Desktop/nwb workshop/Steinmetz2019_Cori_2016-12-14.nwb'
        path: '/general/experimenter'
        dims: 1

For a matNWB defined nwb file, it'll show just string or cell. After exporting and reading, it becomes a dataStub as well, but pynwb still reads it as bytes.

basic interactive df viewer

would be long-term cool to have something like qgrid. In the mean time some sort of simple interaction (so that you can see all of a large table) would be good.

ElectricalSeries widget does not show all available electrode traces

I have created a dummy dataset like in this tutorial:
I'm facing 2 similar issues:

Issue 1:
This is the error I get when I try to visualize the ElectricalSeries:
Could this be because of the numbering of electrodes in the region:
electrode_table_region = nwbfile.create_electrode_table_region([0, 2], 'the first and third electrodes')

TypeError                                 Traceback (most recent call last)
~\Anaconda3\lib\site-packages\h5py\_hl\selections.py in select(shape, args, dsid)
     84             try:
---> 85                 int(a)
     86                 if isinstance(a, np.ndarray) and a.shape == (1,):

TypeError: only size-1 arrays can be converted to Python scalars

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
~\Anaconda3\lib\site-packages\nwbwidgets\utils\widgets.py in observer(change)
     30         with out:
     31             clear_output(wait=True)
---> 32             f(**unpack_controls(controls, process_controls))
     33             show_inline_matplotlib_plots()
     34     for k, w in controls.items():

~\Anaconda3\lib\site-packages\nwbwidgets\timeseries.py in plot_grouped_traces(time_series, time_window, order, ax, figsize, group_inds, labels, colors, show_legend, **kwargs)
    304         order = np.arange(time_series.data.shape[1])
    305 
--> 306     mini_data, tt, offsets = _prep_timeseries(time_series, time_window, order)
    307 
    308     if group_inds is not None:

~\Anaconda3\lib\site-packages\nwbwidgets\timeseries.py in _prep_timeseries(time_series, time_window, order)
    285 
    286     unique_sorted_order, inverse_sort = np.unique(order, return_inverse=True)
--> 287     mini_data = time_series.data[t_ind_start:t_ind_stop, unique_sorted_order][:, inverse_sort]
    288 
    289     gap = np.median(np.nanstd(mini_data, axis=0)) * 20

h5py\_objects.pyx in h5py._objects.with_phil.wrapper()

h5py\_objects.pyx in h5py._objects.with_phil.wrapper()

~\Anaconda3\lib\site-packages\h5py\_hl\dataset.py in __getitem__(self, args)
    551 
    552         # Perform the dataspace selection.
--> 553         selection = sel.select(self.shape, args, dsid=self.id)
    554 
    555         if selection.nselect == 0:

~\Anaconda3\lib\site-packages\h5py\_hl\selections.py in select(shape, args, dsid)
     88             except Exception:
     89                 sel = FancySelection(shape)
---> 90                 sel[args]
     91                 return sel
     92 

~\Anaconda3\lib\site-packages\h5py\_hl\selections.py in __getitem__(self, args)
    399         self._id.select_none()
    400         for idx, vector in enumerate(argvector):
--> 401             start, count, step, scalar = _handle_simple(self.shape, vector)
    402             self._id.select_hyperslab(start, count, step, op=h5s.SELECT_OR)
    403 

~\Anaconda3\lib\site-packages\h5py\_hl\selections.py in _handle_simple(shape, args)
    464         else:
    465             try:
--> 466                 x,y,z = _translate_int(int(arg), length)
    467                 s = True
    468             except TypeError:

~\Anaconda3\lib\site-packages\h5py\_hl\selections.py in _translate_int(exp, length)
    484 
    485     if not 0<=exp<length:
--> 486         raise ValueError("Index (%s) out of range (0-%s)" % (exp, length-1))
    487 
    488     return exp, 1, 1

ValueError: Index (2) out of range (0-1)

Issue 2:
Then I changed the electrode_table_region and ephys_data shape to reflect all 4 defined electrodes in the electrode table:

electrode_table_region = nwbfile.create_electrode_table_region([0,1,2,3], 'all electrodes')
ephys_data = np.random.rand(data_len * 4).reshape((data_len, 4))

using widgets to visualize the ElectricalSeries shows only 3 of the 4 electrode TimeSeries ( even with the units slider all the way up) :
image

AIBS behavior_ophys: Grayscale Image objects

In the current Allen Institute behavior ophys files, there are 2-d numpy arrays for images:

/processing/two_photon_imaging/images/max_projection/data
nwb.modules['two_photon_imaging'].data_interfaces['images'].images['max_projection'].data[:]

Ideally would be a 2-d image viewer, with pan and zoom functionality.

ImageSegmentation makes assumptions that cause error

from pynwb import NWBHDF5IO
fpath = 'Chen 2017/an041_2014-08-21_9.nwb'
nwb = NWBHDF5IO(fpath,'r').read()
nwb2widget(nwb.processing['Ophys']['ImageSegmentation'])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-8d011f7d0524> in <module>
      1 #nwb = NWBHDF5IO(fpath,'r').read()
----> 2 nwb2widget(nwb.processing['Ophys']['ImageSegmentation'])

~/dev/nwb-jupyter-widgets/nwbwidgets/view.py in nwb2widget(node, neurodata_vis_spec)
     51 
     52 def nwb2widget(node,  neurodata_vis_spec=default_neurodata_vis_spec):
---> 53     return base.nwb2widget(node, neurodata_vis_spec)

~/dev/nwb-jupyter-widgets/nwbwidgets/base.py in nwb2widget(node, neurodata_vis_spec, **pass_kwargs)
    171                 return lazy_tabs(spec, node)
    172             elif callable(spec):
--> 173                 return vis2widget(spec(node, neurodata_vis_spec=neurodata_vis_spec, **pass_kwargs))
    174     out1 = widgets.Output()
    175     with out1:

~/dev/nwb-jupyter-widgets/nwbwidgets/ophys.py in show_image_segmentation(img_seg, neurodata_vis_spec)
     54 def show_image_segmentation(img_seg: ImageSegmentation, neurodata_vis_spec: dict):
     55     if len(img_seg.plane_segmentations) == 1:
---> 56         return show_plane_segmentation(next(iter(img_seg.plane_segmentations.values())), neurodata_vis_spec)
     57     else:
     58         return neurodata_vis_spec[NWBDataInterface](img_seg, neurodata_vis_spec)

~/dev/nwb-jupyter-widgets/nwbwidgets/ophys.py in show_plane_segmentation(plane_seg, neurodata_vis_spec)
    135         return show_plane_segmentation_3d(plane_seg)
    136     elif 'image_mask' in plane_seg:
--> 137         return show_plane_segmentation_2d(plane_seg)
    138 
    139 

~/dev/nwb-jupyter-widgets/nwbwidgets/ophys.py in show_plane_segmentation_2d(plane_seg, color_wheel, color_by, threshold)
     85             cats = np.unique(plane_seg[color_by][:])
     86         else:
---> 87             raise ValueError('specified color_by parameter, {}, not in plane_seg object'.format(color_by))
     88     data = plane_seg['image_mask'].data
     89     nUnits = data.shape[0]

ValueError: specified color_by parameter, neuron_type, not in plane_seg object

ipyvolume position trace

When running behavior.show_spatial_series on the Buffalo Lab 2017_5_04_processed.nwb, I get an error I haven't been able to track down:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate(self, obj, value)
   1984         try:
-> 1985             value = float(value)
   1986         except:

TypeError: float() argument must be a string or a number, not 'NoneType'

During handling of the above exception, another exception occurred:

TraitError                                Traceback (most recent call last)
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate_elements(self, obj, value)
   2251             try:
-> 2252                 v = self._trait._validate(obj, v)
   2253             except TraitError:

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in _validate(self, obj, value)
    590         if hasattr(self, 'validate'):
--> 591             value = self.validate(obj, value)
    592         if obj._cross_validation_lock is False:

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate(self, obj, value)
   1986         except:
-> 1987             self.error(obj, value)
   1988         return _validate_bounds(self, obj, value)

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in error(self, obj, value)
    624                 % (self.name, self.info(), repr_type(value))
--> 625         raise TraitError(e)
    626 

TraitError: The 'None' trait of a Figure instance must be a float, but a value of None <class 'NoneType'> was specified.

During handling of the above exception, another exception occurred:

TraitError                                Traceback (most recent call last)
~/opt/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in _handle_msg(self, msg)
    674                 if 'buffer_paths' in data:
    675                     _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 676                 self.set_state(state)
    677 
    678         # Handle a state request.

~/opt/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in set_state(self, sync_data)
    543                     from_json = self.trait_metadata(name, 'from_json',
    544                                                     self._trait_from_json)
--> 545                     self.set_trait(name, from_json(sync_data[name], self))
    546 
    547     def send(self, content, buffers=None):

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in set_trait(self, name, value)
   1341                                 (cls.__name__, name))
   1342         else:
-> 1343             getattr(cls, name).set(self, value)
   1344 
   1345     @classmethod

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in set(self, obj, value)
    557 
    558     def set(self, obj, value):
--> 559         new_value = self._validate(obj, value)
    560         try:
    561             old_value = obj._trait_values[self.name]

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in _validate(self, obj, value)
    589             return value
    590         if hasattr(self, 'validate'):
--> 591             value = self.validate(obj, value)
    592         if obj._cross_validation_lock is False:
    593             value = self._cross_validate(obj, value)

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate(self, obj, value)
   2322 
   2323     def validate(self, obj, value):
-> 2324         value = super(List, self).validate(obj, value)
   2325         value = self.validate_elements(obj, value)
   2326         return value

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate(self, obj, value)
   2240             return value
   2241 
-> 2242         value = self.validate_elements(obj, value)
   2243 
   2244         return value

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate_elements(self, obj, value)
   2319             self.length_error(obj, value)
   2320 
-> 2321         return super(List, self).validate_elements(obj, value)
   2322 
   2323     def validate(self, obj, value):

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in validate_elements(self, obj, value)
   2252                 v = self._trait._validate(obj, v)
   2253             except TraitError:
-> 2254                 self.element_error(obj, v, self._trait)
   2255             else:
   2256                 validated.append(v)

~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in element_error(self, obj, element, validator)
   2231         e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
   2232             % (self.name, class_of(obj), validator.info(), repr_type(element))
-> 2233         raise TraitError(e)
   2234 
   2235     def validate(self, obj, value):

TraitError: Element of the 'matrix_world' trait of a Figure instance must be a float, but a value of None <class 'NoneType'> was specified.

dispatch on dynamictable name

There are numerous dynamic table objects in an nwb file, representing different kinds of data. These are not necessarily distinguished by class, but instead by their columns. It ought to be easy to dispatch behavior by the name of a dynamic table (for instance: units might want to plot mean waveforms).

Full filtering on icephys hierarchical tables

Introduction
This is just an idea on how to visualize the icephys data when hierarchical tables from ndx-icephys-meta are present.
This will:

Proposal
Create listboxes/lists/buttons that allow the user to select one or more items from the lists of unique
cells, conditions, repetitions, stimulus_types, sweeps, intracellular_recordings, [stimulus, response] and dynamically show the plots corresponding to the intersection of selected features.

Example
User selects condition = 1, stimulus_type = A and response.
The responses of all sweeps from all cells and all repetitions for experimental condition 1 and stimulus_type A will be plotted.

ValueError when exploring spatial_series data

This error happens when expanding widgets to look into spatial_series data inside the Position group of Giocomo's lab nwb file:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\Anaconda3\envs\nwbn_conversion\lib\site-packages\ipywidgets\widgets\widget.py in _handle_msg(self, msg)
    674                 if 'buffer_paths' in data:
    675                     _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 676                 self.set_state(state)
    677 
    678         # Handle a state request.

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\ipywidgets\widgets\widget.py in set_state(self, sync_data)
    543                     from_json = self.trait_metadata(name, 'from_json',
    544                                                     self._trait_from_json)
--> 545                     self.set_trait(name, from_json(sync_data[name], self))
    546 
    547     def send(self, content, buffers=None):

~\Anaconda3\envs\nwbn_conversion\lib\contextlib.py in __exit__(self, type, value, traceback)
    117         if type is None:
    118             try:
--> 119                 next(self.gen)
    120             except StopIteration:
    121                 return False

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\traitlets\traitlets.py in hold_trait_notifications(self)
   1129                 for changes in cache.values():
   1130                     for change in changes:
-> 1131                         self.notify_change(change)
   1132 
   1133     def _notify_trait(self, name, old_value, new_value):

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\ipywidgets\widgets\widget.py in notify_change(self, change)
    604                 # Send new state to front-end
    605                 self.send_state(key=name)
--> 606         super(Widget, self).notify_change(change)
    607 
    608     def __repr__(self):

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\traitlets\traitlets.py in notify_change(self, change)
   1174                 c = getattr(self, c.name)
   1175 
-> 1176             c(change)
   1177 
   1178     def _add_notifiers(self, handler, name, type):

c:\users\luiz\documents\github\nwb-jupyter-widgets\nwbwidgets\base.py in on_selected_index(change)
    116         if change.new is not None and isinstance(change.owner.children[change.new], widgets.HTML):
    117             children[change.new] = nwb2widget(list(d.values())[change.new], neurodata_vis_spec=neurodata_vis_spec,
--> 118                                               **pass_kwargs)
    119             change.owner.children = children
    120 

c:\users\luiz\documents\github\nwb-jupyter-widgets\nwbwidgets\base.py in nwb2widget(node, neurodata_vis_spec, **pass_kwargs)
    162             spec = neurodata_vis_spec[ndtype]
    163             if isinstance(spec, dict):
--> 164                 return lazy_tabs(spec, node)
    165             elif callable(spec):
    166                 return vis2widget(spec(node, neurodata_vis_spec=neurodata_vis_spec, **pass_kwargs))

c:\users\luiz\documents\github\nwb-jupyter-widgets\nwbwidgets\base.py in lazy_tabs(in_dict, node)
    142     tabs_spec = list(in_dict.items())
    143 
--> 144     children = [tabs_spec[0][1](node)] + [widgets.HTML('Rendering...')
    145                                           for _ in range(len(tabs_spec) - 1)]
    146     tab = widgets.Tab(children=children)

c:\users\luiz\documents\github\nwb-jupyter-widgets\nwbwidgets\behavior.py in show_spatial_series_over_time(node, **kwargs)
     37     if ndims == 1:
     38         fig, ax = plt.subplots()
---> 39         ax.plot(tt, data, **kwargs)
     40         ax.set_xlabel('t (sec)')
     41         if unit:

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\matplotlib\axes\_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1664         """
   1665         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D._alias_map)
-> 1666         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1667         for line in lines:
   1668             self.add_line(line)

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\matplotlib\axes\_base.py in __call__(self, *args, **kwargs)
    223                 this += args[0],
    224                 args = args[1:]
--> 225             yield from self._plot_args(this, kwargs)
    226 
    227     def get_next_color(self):

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\matplotlib\axes\_base.py in _plot_args(self, tup, kwargs)
    389             x, y = index_of(tup[-1])
    390 
--> 391         x, y = self._xy_from_xy(x, y)
    392 
    393         if self.command == 'plot':

~\Anaconda3\envs\nwbn_conversion\lib\site-packages\matplotlib\axes\_base.py in _xy_from_xy(self, x, y)
    268         if x.shape[0] != y.shape[0]:
    269             raise ValueError("x and y must have same first dimension, but "
--> 270                              "have shapes {} and {}".format(x.shape, y.shape))
    271         if x.ndim > 2 or y.ndim > 2:
    272             raise ValueError("x and y can be no greater than 2-D, but have "

ValueError: x and y must have same first dimension, but have shapes (81863,) and (81862,)

AIBS behavior_ophys: stimulus_templates are shaped (k, m, n)

In the current Allen Institute behavior ophys files, there are 3-d numpy arrays for stimulus presentations:

/stimulus/templates/Natural_Images_Lum_Matched_set_training_2017.07.14/data

When browsed, it appears that the framework is expecting a 2-D (m, n) array.

Bug fix/enhancement is to provide a selector to choose the k-th image, and plot the slice (i.e. data[k,:,:]).

nwb.stimulus['Natural_Images_Lum_Matched_set_training_2017.07.14'].data[:]

Integrate electrode/cell for icephys hierarchical tables

At the moment, within a single file, the widget merges together the repetitions of different cells, apparently in the following order: [rep1 cell1], [rep1, cell2], [rep2, cell1], [rep2, cell2] etc

image

Plots from different cells should somehow be displayed separately.

Answering to @bendichter:

How do you suggest we fix this? We could have multiple rows, one for each cell. Then the columns would be reps and the rows would be cells.

Although this is perhaps the simplest view, I think this is not how experimenters see their data, because cells are not always directly comparable.

Can we assume the stimuli are the same for each cell for a given sweep?

If I understand the question correctly: no, you can't assume this. For example, the starting amperage of a stimulus will change depending on the electrical properties of a specific cell: so you can't skip plotting the stimuli, if this is why you were asking. During analysis, typically some normalization occurs.

Phrased another way, what is the most natural way of exploring this data? The way I described would be
session -> stimulus_type -> cell & rep -> stimulus & response
but another way could be
session -> cell -> stimulus_type -> rep -> stimulus & response

Because of the previous answer, I would go with the second, with the possibility to preserve the user choice of stimulus_type and rep between switches between cells.
So cell x buttons/tabs should be at the very top, outside of the stimulus_type - repetition accordion.

and then for the runs table, we were thinking
rep -> stimulus_type -> stimulus & response
I can put these in basically any hierarchical order. Maybe I should make that flexible? Would that be too much?

Sounds good this way. I would keep it simple until further user requests. Of course, cells should appear the way it appears for the repetitions (described above).

ModuleNotFoundError: No module named 'nwbwidgets.utils'

Installed form the current repo version.
When importing, I get the error:

from nwbwidgets import nwb2widget
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-33af5fa05d5c> in <module>
      1 from pynwb import NWBFile, NWBHDF5IO
----> 2 from nwbwidgets import nwb2widget
      3 
      4 import scipy.io
      5 import numpy as np

~\Anaconda3\envs\convert_to_nwb\lib\site-packages\nwbwidgets\__init__.py in <module>
----> 1 from .view import nwb2widget

~\Anaconda3\envs\convert_to_nwb\lib\site-packages\nwbwidgets\view.py in <module>
      3 import pynwb
      4 from collections import OrderedDict
----> 5 from nwbwidgets import behavior, misc, base, ecephys, image, ophys
      6 from matplotlib.pyplot import Figure
      7 from pynwb.base import ProcessingModule

~\Anaconda3\envs\convert_to_nwb\lib\site-packages\nwbwidgets\ophys.py in <module>
      4 from pynwb.base import NWBDataInterface
      5 from collections import OrderedDict
----> 6 from .utils.cmaps import linear_transfer_function
      7 
      8 

ModuleNotFoundError: No module named 'nwbwidgets.utils'

change foreign controllers API

Following conversation with @luiztauffer

Controllers should be specified in the following way:

There should be an optional arg in the constructor of a widget such as time_window_controller.

  • time_window_controller='auto' (default) will automatically determine if a controller is necessary. For instance, with a time_window, it will only create a controller if the time series is greater than 30 seconds in length. If it is necessary, it will create an internal controller with the default type.
  • time_window_controller='internal' will create a TimeWindowController of the default type internal to the widget.
  • time_window_controller=start_and_duration_controller, where start_and_duration_controller, is an instance of TimeWindowController: start_and_duration_controller will act as a foreign controller. This is generally used if you want a controller to control more than one widget simultaneously, or if you want the controller to be placed spatially in a different place in the dashboard.
  • time_window_controller=StartAndDurationController where StartAndDurationController is a class that is a subtype of of TimeWindowController: An internal time window controller will be created using type StartAndDurationController.
  • time_window_controller=False will not create a time window controller.

Luiz, is this what you imagined? I think this would cover all the bases.

Documentation Bug for Calcium Imaging Data Tutorial

Description

I tried viewing the file created in the pynwb Calcium Imaging Data tutorial in a Jupyter notebook with NWB2Widgets. When viewing the the image segmentation group, I got an error message.

Steps to Reproduce

  1. Go to: https://pynwb.readthedocs.io/en/stable/tutorials/domain/ophys.html#sphx-glr-tutorials-domain-ophys-py

  2. At the bottom of the page, select Download Jupyter notebook: Ophys.ipynb

  3. Open notebook and paste the following code at the bottom:

from nwbwidgets import nwb2widget
io = NWBHDF5IO('ophys_example.nwb', mode='r')
nwb = io.read()
nwb2widget(nwb)

  1. Select the processing module >ophys>ImageSegmentation.

  2. After waiting a while for rendering, I got the following error:

Notebook validation failed: {'version_major': 2, 'version_minor': 0, 'model_id': '87c09359c2074c13891ca080691a0f53'} is not valid under any of the given schemas:
{
"version_major": 2,
"version_minor": 0,
"model_id": "87c09359c2074c13891ca080691a0f53"
}

Environment

Python Executable: Conda
Python Version: 3.7
Operating System: Windows
HDMF Version: pynwb 1.3.0

Checklist

  • [x ] Have you ensured the feature or change was not already [reported]
    It may be related to NeurodataWithoutBorders/pynwb#1192, but since I am using the latest release, I wanted to raise the issue.

(https://github.com/NeurodataWithoutBorders/pynwb/issues)?

  • [ x] Have you included a brief and descriptive title?
  • [ x] Have you included a clear description of the problem you are trying to solve?
  • [x ] Have you included a minimal code snippet that reproduces the issue you are encountering?
  • [ x] Have you checked our Contributing document?

Index out of range for second Electrical Series

Hi, I created two ElectricalSeries objects in my nwb file. Each of them has their own electrode table region (one goes from 0-166, another goes from 167-183). Both acquisitions show up in the widget, but the acquisition ranging from 167-183 produces the following error: ValueError: Index (167) out of range (0-15). I don't think this is an error with the table regions but I could be mistaken. I also checked that both acquisitions have the correct number of channels and the file worked with pynwb.validate(). Any help would be useful. Thank you

Noah

valueerror when opening timestamps

I'm looking at a running speed. Rendering the data works fine but the timestamps fail as follows:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/miniconda3/envs/py37/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in _handle_msg(self, msg)
    667                 if 'buffer_paths' in data:
    668                     _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 669                 self.set_state(state)
    670 
    671         # Handle a state request.

~/miniconda3/envs/py37/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in set_state(self, sync_data)
    537                     from_json = self.trait_metadata(name, 'from_json',
    538                                                     self._trait_from_json)
--> 539                     self.set_trait(name, from_json(sync_data[name], self))
    540 
    541     def send(self, content, buffers=None):

~/miniconda3/envs/py37/lib/python3.7/contextlib.py in __exit__(self, type, value, traceback)
    117         if type is None:
    118             try:
--> 119                 next(self.gen)
    120             except StopIteration:
    121                 return False

~/miniconda3/envs/py37/lib/python3.7/site-packages/traitlets/traitlets.py in hold_trait_notifications(self)
   1129                 for changes in cache.values():
   1130                     for change in changes:
-> 1131                         self.notify_change(change)
   1132 
   1133     def _notify_trait(self, name, old_value, new_value):

~/miniconda3/envs/py37/lib/python3.7/site-packages/ipywidgets/widgets/widget.py in notify_change(self, change)
    598                 # Send new state to front-end
    599                 self.send_state(key=name)
--> 600         super(Widget, self).notify_change(change)
    601 
    602     def __repr__(self):

~/miniconda3/envs/py37/lib/python3.7/site-packages/traitlets/traitlets.py in notify_change(self, change)
   1174                 c = getattr(self, c.name)
   1175 
-> 1176             c(change)
   1177 
   1178     def _add_notifiers(self, handler, name, type):

~/Desktop/nwb_janelia/nwb_jupyter/nwb-jupyter-widgets/nwbwidgets/view.py in on_selected_index(change)
     25     def on_selected_index(change):
     26         if change.new is not None and isinstance(change.owner.children[change.new], widgets.HTML):
---> 27             children[change.new] = nwb2widget(list(d.values())[change.new], neurodata_vis_spec=neurodata_vis_spec)
     28             change.owner.children = children
     29 

~/Desktop/nwb_janelia/nwb_jupyter/nwb-jupyter-widgets/nwbwidgets/view.py in nwb2widget(node, neurodata_vis_spec)
     90                 return tab
     91             elif callable(spec):
---> 92                 return vis2widget(spec(node, neurodata_vis_spec=neurodata_vis_spec))
     93     out1 = widgets.Output()
     94     with out1:

~/Desktop/nwb_janelia/nwb_jupyter/nwb-jupyter-widgets/nwbwidgets/base.py in show_timeseries(node, **kwargs)
     15     fig, ax = plt.subplots()
     16     if node.timestamps:
---> 17         ax.plot(node.timestamps, node.data)
     18     else:
     19         ax.plot(np.arange(len(node.data)) / node.rate + node.starting_time, node.data)

~/miniconda3/envs/py37/lib/python3.7/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1808                         "the Matplotlib list!)" % (label_namer, func.__name__),
   1809                         RuntimeWarning, stacklevel=2)
-> 1810             return func(ax, *args, **kwargs)
   1811 
   1812         inner.__doc__ = _add_data_doc(inner.__doc__,

~/miniconda3/envs/py37/lib/python3.7/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, *args, **kwargs)
   1609         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D._alias_map)
   1610 
-> 1611         for line in self._get_lines(*args, **kwargs):
   1612             self.add_line(line)
   1613             lines.append(line)

~/miniconda3/envs/py37/lib/python3.7/site-packages/matplotlib/axes/_base.py in _grab_next_args(self, *args, **kwargs)
    391                 this += args[0],
    392                 args = args[1:]
--> 393             yield from self._plot_args(this, kwargs)
    394 
    395 

~/miniconda3/envs/py37/lib/python3.7/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs)
    351         # downstream.
    352         if any(v is None for v in tup):
--> 353             raise ValueError("x, y, and format string must not be None")
    354 
    355         kw = {}

ValueError: x, y, and format string must not be None

A two-axis plot of the timestamps doesn't really make sense anyways - they are just points in one dimension.

showing videos

videos can be added as widgets using https://github.com/Who8MyLunch/Jupyter_Video_Widget with the following code:

from jpy_video import Video
from ipywidgets import widgets

vid = Video(fpath)

time_slider = widgets.FloatSlider(
        value=0.,
        min=0.,
        max=50.,
        step=0.1,
        description='time',
        continuous_update=False,
        orientation='horizontal',
        readout=True,
        readout_format='.1f')

controls = {'time': time_slider}

def update_vid(time):
    vid.set_property('currentTime', time)

out_vid = widgets.interactive_output(update_vid, controls)
vbox = widgets.VBox(children=[time_slider, vid])
vbox

It would be great to have this implemented for ImageSeries objects, particularly those with external references to standard video files.

Installation issues and versioning

Hi @bendichter

I found a few small issues regarding installation/versioning:

Installation

A fresh install on a new environment fails because of a mismatch in dependencies:

conda create -n nwbtest python=3.7
python setup.py develop

Error:
error: ipywidgets 8.0.0a0 is installed but ipywidgets<8.0,>=7.5.0 is required by {'ipysheet', 'ipytree'}

A simple fix is removing ipywidgets from the reqiorements and let ipysheet install the right version.

Versions

The version on pypi is 0.5.1, but in setup.py is 0.5.0. Also the __version__ is not present. I added a version.py so that it can be the only place that keeps the right version. That is accessed both by the setup.py and by the __init__.py as __version__

Not working with pynwb v1.2.1

Hi,
when importing nwbwidgets with pynwb v1.2.1 installed the following error occurs:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/conda/envs/nwb/lib/python3.7/site-packages/nwbwidgets/__init__.py", line 1, in <module>
    from .view import nwb2widget
  File "/opt/conda/envs/nwb/lib/python3.7/site-packages/nwbwidgets/view.py", line 6, in <module>
    from nwbwidgets import behavior, misc, base, ecephys, image, ophys
  File "/opt/conda/envs/nwb/lib/python3.7/site-packages/nwbwidgets/base.py", line 8, in <module>
    from pynwb.core import DynamicTable, NWBBaseType
ImportError: cannot import name 'NWBBaseType' from 'pynwb.core' (/opt/conda/envs/nwb/lib/python3.7/site-packages/pynwb/core.py)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.