Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: add initial streamline widget #4

Merged
merged 11 commits into from
Apr 22, 2018
Merged

Conversation

satra
Copy link
Member

@satra satra commented Sep 24, 2017

added a streamline widget. usage example here: https://nbviewer.jupyter.org/urls/dl.dropbox.com/s/oukfh9agca5k9im/streamlines.ipynb

this requires a few changes to ipyvolume that i will be submitting as a PR shortly.

additional things to consider:

  • use header information for size and affine
  • allow different coloring schemes, although per vertex colors are quite slow
  • allow support for a streamline object in addition to a file
  • allow more control for figure options (view, zoom, etc.,.)

@satra
Copy link
Member Author

satra commented Sep 24, 2017

needs: widgetti/ipyvolume#72

@janfreyberg
Copy link
Contributor

any chance you could make a .trk file available to try this out?

@satra
Copy link
Member Author

satra commented Sep 27, 2017

@janfreyberg
Copy link
Contributor

Thanks.

For some reason I can't get it to work - it doesn't work with ipyvolume from pypi but even if I install from your repo with the fix it's throwing errors. I'll wait until your fix is merged and try it out then!

@satra
Copy link
Member Author

satra commented Sep 27, 2017

$ wget https://github.com/satra/ipyvolume/archive/enh/line-visibility-control.zip

unzip and cd to the ipyvolume folder

$ pip install -e .
$ jupyter nbextension install --py --symlink --sys-prefix ipyvolume
$ jupyter nbextension enable --py --sys-prefix ipyvolume

note these last steps set up ipyvolume in dev mode and requires nodejs. and any jupyter instance needs to be restarted for this to take effect.

@arokem
Copy link
Member

arokem commented Sep 27, 2017

I tried following this and am getting:


D-173-250-183-82:~  $jupyter nbextension install --py --symlink --sys-prefix ipyvolume
Traceback (most recent call last):
  File "/Users/arokem/anaconda3/bin/jupyter-nbextension", line 11, in <module>
    load_entry_point('notebook', 'console_scripts', 'jupyter-nbextension')()
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/jupyter_core/application.py", line 267, in launch_instance
    return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/traitlets/config/application.py", line 658, in launch_instance
    app.start()
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/notebook/nbextensions.py", line 900, in start
    super(NBExtensionApp, self).start()
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/jupyter_core/application.py", line 256, in start
    self.subapp.start()
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/notebook/nbextensions.py", line 678, in start
    self.install_extensions()
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/notebook/nbextensions.py", line 657, in install_extensions
    **kwargs
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/notebook/nbextensions.py", line 211, in install_nbextension_python
    m, nbexts = _get_nbextension_metadata(module)
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/notebook/nbextensions.py", line 1034, in _get_nbextension_metadata
    m = import_item(module)
  File "/Users/arokem/anaconda3/lib/python3.5/site-packages/traitlets/utils/importstring.py", line 42, in import_item
    return __import__(parts[0])
  File "/Users/arokem/source/ipyvolume/ipyvolume/__init__.py", line 10, in <module>
    from .pylab import *
  File "/Users/arokem/source/ipyvolume/ipyvolume/pylab.py", line 362, in <module>
    size_selected=1, size=1, connected=True, visible_markers=False,
  File "/Users/arokem/source/ipyvolume/ipyvolume/pylab.py", line 25, in _docsubst
    f.__doc__ = f.__doc__.format(**_doc_snippets)
KeyError: 'visible_lines'

Any ideas?

@satra
Copy link
Member Author

satra commented Sep 27, 2017

@arokem - hold on based on a conversion on ipyvolume i sent some updates that i didn't test. perhaps those are inappropriate. give me a minute to check.

@satra
Copy link
Member Author

satra commented Sep 27, 2017

@arokem - try now - you will have to wget the zip file again.

@arokem
Copy link
Member

arokem commented Sep 27, 2017

Yep - installing/enabling seems to work now! Thanks!

@satra
Copy link
Member Author

satra commented Oct 28, 2017

@janfreyberg, @arokem - this does require ipyvolume master, but it works well now at scale.

once this branch is installed together with ipyvolume master, you can test with:

https://www.dropbox.com/s/oukfh9agca5k9im/streamlines.ipynb?dl=0

https://www.dropbox.com/s/dbexuhk7fsawvox/streamlines.trk?dl=0

@satra
Copy link
Member Author

satra commented Oct 28, 2017

@arokem - with this new mechanism, it would not take much work to refactor to draw bundles.

@janfreyberg
Copy link
Contributor

Thanks, will test this ASAP. Any idea yet when the required changes will be released by ipyvolume?

@janfreyberg
Copy link
Contributor

Working great for me, awesome!

image

Two thoughts I have:

  • allowing people to pass in a nibabel.streamlines structure, rather than just a filename - in case people have them loaded in memory rather than saved to disk
  • so far there's no documentation on colors, would be nice to include this as well

Copy link
Member

@arokem arokem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small comments from my end.

def color(x):
"""Returns an approximation for color of line based on its endpoints"""
dirvec = (x[0, :] - x[-1, :])
return (dirvec/(np.sqrt(np.sum(dirvec*dirvec, axis=-1)))).dot(np.eye(3))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this do the same thing as this?

https://github.com/nipy/dipy/blob/master/dipy/viz/colormap.py#L211-L240

I'm not sure it does.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given this line, https://github.com/nipy/dipy/blob/master/dipy/viz/colormap.py#L257, i think they are doing exactly the same thing. line 19 can be simplified because i'm not really using anything other than rgb extremes. but instead of eye, one could use three different colors in the colorspace, and a non-linearity on the normalized direction vector.


Args
----
skip : int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explanation of this parameter could be understood as the number of streamlines to omit from the beginning of the collection, or something of that sort.

Might be easier if it is formulated as proportion_to_display, from which the skip is calculated.

BTW: the default here and in the _default_plotter method is different. Is that intentional?

Also, what would a None input do here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None would use all streamlines. i will change this to proportion_to_display.

the defaults were not updated since the efficiency boost. initially we couldn't display more than 5k lines, but now it can handle much more.

@satra
Copy link
Member Author

satra commented Nov 2, 2017

@janfreyberg - thanks for the review. those suggestions are great. whenever i get some time next, i'll add those in together with @arokem's suggestions.

* upstream/master:
  Update path to repos for direct pip install from git
  niwidget_volume- delete os import
  Added flipping to the left for sagittal view
  version number change
  Some formatting changes
  allow taking in nifti file
  Use the scaled rather than the unscaled data stored in nifti file
  change default for background masking
  Backwards compatibility to 3.5 Revert from using Path's `strict` kwarg to using explicit file check, since `strict` was only added in 3.6.
@satra
Copy link
Member Author

satra commented Feb 14, 2018

@arokem and @janfreyberg - finally got to this. should have all the pieces in place now.

  • added small data file in example data
  • updated index.ipynb with streamline example
  • updated api of streamlinewidget to take file or streamline
  • updated plot api to use display_fraction

@satra
Copy link
Member Author

satra commented Feb 23, 2018

@arokem and @janfreyberg - any chance this can be reviewed soon.

@arokem
Copy link
Member

arokem commented Feb 23, 2018

Did your changes make it upstream to current ipyvolume?

@satra
Copy link
Member Author

satra commented Feb 24, 2018

Did your changes make it upstream to current ipyvolume?

yes

Copy link
Member

@arokem arokem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, and works well. I had a couple of small comments, and found one error that should be easy to work around. +1 from my end for the merge, once these small things are resolved.

@@ -25,3 +25,5 @@
surface_dir / f
for f in ('lh.area', 'lh.curv', 'lh.thickness', 'lh.aparc.annot')
]

streamlines = root_dir / 'streamlines.trk'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this returns a PosixPath object, the example in the index file raises an error, unless I pass sw = StreamlineWidget(filename=streamlines.as_posix())

----
filename : str
The path to your ``.trk`` file. Can be a string, or a
``PosixPath`` from python3's pathlib.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PosixPath doesn't work for me. Raises:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-09a88a08f323> in <module>()
----> 1 sw = StreamlineWidget(filename=streamlines)
      2 
      3 style = {'axes': {'color': 'red',
      4                   'label': {'color': 'white'},
      5                   'ticklabel': {'color': 'white'},

~/source/niwidgets/niwidgets/streamlines.py in __init__(self, filename, streamlines)
     41 
     42         if filename:
---> 43             if not os.path.isfile(filename):
     44                 # for Python3 should have FileNotFoundError here
     45                 raise IOError('file {} not found'.format(filename))

~/anaconda3/lib/python3.5/genericpath.py in isfile(path)
     28     """Test whether a path is a regular file"""
     29     try:
---> 30         st = os.stat(path)
     31     except OSError:
     32         return False

TypeError: argument should be string, bytes or integer, not PosixPath

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm curious as to your environment:

on my osx with py36 i get this:

In [1]: from niwidgets.exampledata import streamlines

In [2]: streamlines
Out[2]: PosixPath('/software/nipy-repo/niwidgets/niwidgets/data/streamlines.trk')

In [3]: from niwidgets.streamlines import StreamlineWidget

In [4]: sw = StreamlineWidget(filename=streamlines)


class StreamlineWidget:
"""
Turns mrtrix track or trackvis files into interactive plots using ipyvolume.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The safest here would be to say that this can use any file type that nibabel knows how to read. This will be true even for future versions that implement reading of any other streamline file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roger.

@janfreyberg janfreyberg merged commit 3d59f58 into nipy:master Apr 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants