Data types
Overview
navis
is a Python package for analysing, manipulating and visualizing neurons.
pymaid
lets you interface with a CATMAID server such as those hosted by VFB.
Both packages have extensive documentation (navis | pymaid) with introductory tutorials, examples and a list of all available functions.
Basic datatypes: neurons and neuron lists
navis
knows three types of neurons:
TreeNeurons
= skeletons, e.g. from CATMAIDMeshNeurons
= meshes, e.g. from the hemibrain segmentationDotprops
= points + tangent vectors (typically only used for NBLAST)
Collections of neurons are typically held in a specialized container: aNeuronList
.
Neurons
In this notebook we will focus on skeletons - a.k.a. TreeNeurons
- since this is what you get out of CATMAID. Let’s kick things off by having a look at what neurons look like once it’s loaded:
import navis
# Load one of the example neurons shipped with navis
# (these are olfactory projection neurons from the hemibrain data set)
n = navis.example_neurons(1, kind='skeleton')
# Print some basic info
n
WARNING: Could not load OpenGL library.
type | navis.TreeNeuron |
---|---|
name | 1734350788 |
id | 1734350788 |
n_nodes | 4465 |
n_connectors | None |
n_branches | 603 |
n_leafs | 619 |
cable_length | 266457.994591 |
soma | [4176] |
units | 8 nanometer |
Above summary lists a couple of (computed) properties of the neuron. Each of those can also be accessed directly like so:
n.id
1734350788
There are many more properties that you might find interesting! In theory, you can use type n.
and TAB to get auto-complete suggestions of available properties and methods.
Deepnote appears to have problems with that sometimes - you can fall back to good ‘ole dir()
in that case.
Here is an (incomplete) list of some of the more relevant properties:
bbox
: bounding box of the neuroncable_length
: cable lengthid
: every neuron has an IDnodes
: the SWC node table underlying the neuron
And a couple of class methods:
reroot
: reroot neuronplot2d
/plot3d
: plot the neuron (see also subsequent lessons)copy
: make and return a copyprune_twigs
: remove small terminal twigs
At this point I encourage you to just explore and play around with what TreeNeuron has to offer. Also check out the docs!
As an example: this is how you get the ID of this neuron’s root node.
# Current root node of this neuron
n.root
array([1], dtype=int32)
Some of the properties such as .root
or .ends
are computed on-the-fly from the underlying raw data. For TreeNeurons
that’s the node table (and it’s graph representation). The node table is a pandas DataFrame that looks effectively like a SWC:
# `.head()` gives us the first couple rows
n.nodes.head()
node_id | label | x | y | z | radius | parent_id | type | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 15784.0 | 37250.0 | 28102.0 | 10.000000 | -1 | root |
1 | 2 | 0 | 15764.0 | 37230.0 | 28102.0 | 18.284300 | 1 | slab |
2 | 3 | 0 | 15744.0 | 37190.0 | 28142.0 | 34.721401 | 2 | slab |
3 | 4 | 0 | 15744.0 | 37150.0 | 28182.0 | 34.721401 | 3 | slab |
4 | 5 | 0 | 15704.0 | 37130.0 | 28242.0 | 34.721401 | 4 | slab |
The methods (such as .reroot
) are short-hands for main navis functions:
# Reroot neuron to another node
n2 = n.reroot(new_root=2)
# Print the new root -> expect "2"
n2.root
array([2])
# Instead of calling the shorthand method, we can also do this
n3 = navis.reroot_neuron(n, new_root=2)
n3.root
array([2])
NeuronLists
In practice you will likely work with multiple neurons at a time. For that, navis
has a convenient container: NeuronLists
# Get more than one example neuron
nl = navis.example_neurons(5)
# `nl` is a NeuronList
type(nl)
navis.core.neuronlist.NeuronList
# You can also create neuron lists yourself
my_nl = navis.NeuronList(n)
In many ways NeuronLists
work like Python-lists with a couple of extras:
# Calling just the neuronlist produces a summary
nl
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1734350788 | 1734350788 | 4465 | None | 603 | 619 | 266457.994591 | [4176] | 8 nanometer |
1 | navis.TreeNeuron | 1734350908 | 1734350908 | 4845 | None | 733 | 760 | 304277.007958 | [6] | 8 nanometer |
2 | navis.TreeNeuron | 722817260 | 722817260 | 4336 | None | 635 | 658 | 274910.568784 | None | 8 nanometer |
3 | navis.TreeNeuron | 754534424 | 754534424 | 4702 | None | 697 | 727 | 286742.998887 | [4] | 8 nanometer |
4 | navis.TreeNeuron | 754538881 | 754538881 | 4890 | None | 626 | 642 | 291434.992623 | [703] | 8 nanometer |
# Get a single neuron from the neuronlist
nl[1]
type | navis.TreeNeuron |
---|---|
name | 1734350908 |
id | 1734350908 |
n_nodes | 4845 |
n_connectors | None |
n_branches | 733 |
n_leafs | 760 |
cable_length | 304277.007958 |
soma | [6] |
units | 8 nanometer |
neuronlists
also support fancy indexing similar to numpy
arrays:
# Get multiple neurons from the neuronlist
nl[[1, 2]]
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1734350908 | 1734350908 | 4845 | None | 733 | 760 | 304277.007958 | [6] | 8 nanometer |
1 | navis.TreeNeuron | 722817260 | 722817260 | 4336 | None | 635 | 658 | 274910.568784 | None | 8 nanometer |
# Slicing is also supported
nl[1:3]
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1734350908 | 1734350908 | 4845 | None | 733 | 760 | 304277.007958 | [6] | 8 nanometer |
1 | navis.TreeNeuron | 722817260 | 722817260 | 4336 | None | 635 | 658 | 274910.568784 | None | 8 nanometer |
Strings will be matched against the neurons’ names.
# Get neuron(s) by their name
nl['754534424']
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 754534424 | 754534424 | 4702 | None | 697 | 727 | 286742.998887 | [4] | 8 nanometer |
neuronlists
have a special .idx
indexer that let’s you select neurons by their ID
# Get neuron(s) by their ID
# -> note that for example neurons name == id
nl.idx[[754534424, 722817260]]
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 754534424 | 754534424 | 4702 | None | 697 | 727 | 286742.998887 | [4] | 8 nanometer |
1 | navis.TreeNeuron | 722817260 | 722817260 | 4336 | None | 635 | 658 | 274910.568784 | None | 8 nanometer |
# Access properties across neurons -> returns numpy arrays
nl.n_nodes
array([4465, 4845, 4336, 4702, 4890])
# Select neurons by given property
# -> this works with any boolean array
nl[nl.n_nodes >= 4500]
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | |
---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | 1734350908 | 1734350908 | 4845 | None | 733 | 760 | 304277.007958 | [6] | 8 nanometer |
1 | navis.TreeNeuron | 754534424 | 754534424 | 4702 | None | 697 | 727 | 286742.998887 | [4] | 8 nanometer |
2 | navis.TreeNeuron | 754538881 | 754538881 | 4890 | None | 626 | 642 | 291434.992623 | [703] | 8 nanometer |
Exercises:
- Select the first and the last neuron in the neuronlist
- Select all neurons with a soma
- Select all neurons with a soma and less than 300,000 cable length
Further reading: https://navis.readthedocs.io/en/latest/source/tutorials/neurons_intro.html
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.