Documentation

Exploring Neurons in Navis

How to explore the properties of TreeNeurons using navis.

27 Dec 2021

Overview

navis is a Python package for analysing, manipulating and visualizing neurons. Official documentation here.

Basic datatypes: neurons and neuron lists

navis knows three types of neurons:

  1. TreeNeurons = skeletons, e.g. from CATMAID
  2. MeshNeurons = meshes, e.g. from the hemibrain segmentation
  3. Dotprops = points + tangent vectors (typically only used for NBLAST)

Collections of neurons are typically held in a specialized container: a NeuronList.

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.

typenavis.TreeNeuron
name1734350788
id1734350788
n_nodes4465
n_connectorsNone
n_branches603
n_leafs619
cable_length266457.994591
soma[4176]
units8 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! Typing n. and pressing TAB should give auto-complete suggestions of available properties and methods. If your notebook editor has problems with that, you can fall back to using dir().

Here is an (incomplete) list of some of the more relevant properties:

  • bbox: bounding box of the neuron
  • cable_length: cable length
  • id: every neuron has an ID
  • nodes: the SWC node table underlying the neuron

And some class methods:

  • reroot: reroot neuron
  • plot2d/plot3d: plot the neuron (see also plotting turorial)
  • copy: make and return a copy
  • prune_twigs: remove small terminal twigs

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 its 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_idlabelxyzradiusparent_idtype
01015784.037250.028102.010.000000-1root
12015764.037230.028102.018.2843001slab
23015744.037190.028142.034.7214012slab
34015744.037150.028182.034.7214013slab
45015704.037130.028242.034.7214014slab

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

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron173435078817343507884465None603619266457.994591[4176]8 nanometer
1navis.TreeNeuron173435090817343509084845None733760304277.007958[6]8 nanometer
2navis.TreeNeuron7228172607228172604336None635658274910.568784None8 nanometer
3navis.TreeNeuron7545344247545344244702None697727286742.998887[4]8 nanometer
4navis.TreeNeuron7545388817545388814890None626642291434.992623[703]8 nanometer
# Get a single neuron from the neuronlist
nl[1]

typenavis.TreeNeuron
name1734350908
id1734350908
n_nodes4845
n_connectorsNone
n_branches733
n_leafs760
cable_length304277.007958
soma[6]
units8 nanometer

neuronlists also support fancy indexing similar to numpy arrays:

# Get multiple neurons from the neuronlist
nl[[1, 2]]

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron173435090817343509084845None733760304277.007958[6]8 nanometer
1navis.TreeNeuron7228172607228172604336None635658274910.568784None8 nanometer
# Slicing is also supported
nl[1:3]

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron173435090817343509084845None733760304277.007958[6]8 nanometer
1navis.TreeNeuron7228172607228172604336None635658274910.568784None8 nanometer

Strings will be matched against the neurons’ names.

# Get neuron(s) by their name
nl['754534424']

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron7545344247545344244702None697727286742.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]]

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron7545344247545344244702None697727286742.998887[4]8 nanometer
1navis.TreeNeuron7228172607228172604336None635658274910.568784None8 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]

typenameidn_nodesn_connectorsn_branchesn_leafscable_lengthsomaunits
0navis.TreeNeuron173435090817343509084845None733760304277.007958[6]8 nanometer
1navis.TreeNeuron7545344247545344244702None697727286742.998887[4]8 nanometer
2navis.TreeNeuron7545388817545388814890None626642291434.992623[703]8 nanometer

Exercises:

  1. Select the first and the last neuron in the neuronlist
  2. Select all neurons with a soma
  3. 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