Skip to content

Version 2 Roadmap #153

Closed
Closed
@schlegelp

Description

@schlegelp

This issue is to suggest & discuss (read: spitball) potential breaking changes that might warrant a new major version.

Plotting

Over the past months I have experimented more with the pygfx library and I'm pretty much set on replacing the current vispy-based 3d viewer with octarine. This may well happen already in the next minor version (see #138) but I wonder if a general refactoring of the plotting interface is in order. In particular:

  • Do we want to add pygfx as a 2d plotting backend (see also fastplotlib)? It's much faster and perspectively correct (unlike matplotlib).
  • In general, I think the plotting should be refactored into classes under the hood instead of the current convoluted functions.
  • Further to the above: I would love to play around trying a "Grammar of Graphics"-like interface e.g. via method chaining.

Additional backends

Currently, navis can utilize multiple CPUs (via pathos) but it doesn't scale beyond a single machine. It'd be nice if there was an easy way to divvy up e.g. a big NBLAST across multiple nodes. @aschampion has already made a start in #111 for a Dask backend and the implementation is generic so that it would be easy to tack on more.

Neuron Classes

Two things that have been on my mind with regards to neurons:

  1. As discussed with @bdpedigo in Berlin, can we generate a "unified" neuron object that combines multiple representations (skeleton, mesh, image)? @ceesem has done something similar in MeshParty.

  2. The current neuron names (TreeNeuron, MeshNeuron, VoxelNeuron) are... ugly

It would be nice if there was only a single Neuron class that could be either a single type or multiple. Something along these lines:

>>> swc = pd.read_table('neuron.swc')  # load some SWC table
>>> n = navis.Neuron(swc)  # automatically interprets that this is a skeleton
>>> # Alternatively: n = navis.Neuron.from_swc('neuron.swc') or n = navis.read_swc('neuron.swc')
>>> n
<navis.Neuron(id=12345, type=skeleton, nodes=4320)>
>>> n.type
("skeleton", )

Combining multiple representations could then look like this:

>>> n = navis.Neuron.from_swc('neuron.swc')
>>> n.add_mesh(mesh)
>>> Alternatively: n = navis.Neuron(skeleton=swc, mesh=mesh)
>>> n 
<navis.Neuron(id=12345, type=(skeleton, mesh), nodes=4320, faces=20432)>
>>> n.type
("skeleton", "mesh")

Individual representations can be accessed like this:

>>> n.skeleton  # this can also be generated on-the-fly from the mesh
<navis.Skeleton(id=12345, faces=20432)>
>>> n.mesh
<navis.Mesh(id=12345, faces=20432)>
>>> navis.plot3d(n)  # plots the "first" representation (what that is tbd)
>>> navis.plot3d(n.skeleton)  # explicitly plot the skeleton

Under-the-hood navis already combines representations when needed. For example, navis.prune_twigs works on MeshNeurons by (a) skeletonizing the mesh, (b) pruning the skeleton and (c) removing faces corresponding to the removed skeleton nodes from the mesh. The big question then is: does making this explicity actually simplify things for the user? I imagine that most users will work with either skeletons or meshes and don't need to know how things happen under-the-hood.

I will add above list as I think of more stuff.

Perhaps some of the above can be tackled in a longer hackathon?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions