navis lets you import neurons from a variety of local and remote sources. In this tutorial you will learn how to load skeletons from local data and - failing that - construct them from scratch. For loading remote data (e.g. the MICrONS, neuromorpho, Virtual Fly Brain or Janelia hemibrain datasets), navis has dedicated interfaces. See the example gallery for tutorials on these.

Skeletons in navis are represented by the navis.TreeNeuron class. You can either construct these manually (see bottom of this page) or use one of the built-in functions to them from one of the various file formats:

SWC files

SWC is a common format for storing neuron skeletons. Thus navis provides functions to both read and write SWC files. To demo these, we will be using supplemental data from Bates, Schlegel et al. (Current Biology, 2020). If you want to follow along, please download Supplemental Data S1 (link). If you do, make sure to adjust the filepath accordingly.

import navis

I extracted the archive with the supplemental data inside my downloads folder. It contains a bunch of CSV files with meta data but the important file for us is the Now you could extract that zip archive too but navis can actually read directly from (and write to) zip files!

skeletons = navis.read_swc('~/Downloads/mmc2/', include_subdirs=True)
<class 'navis.core.neuronlist.NeuronList'> containing 480 neurons (101.1MiB)
type name n_nodes n_connectors n_branches n_leafs cable_length soma units created_at origin
0 navis.TreeNeuron 1313071 11634 None 600 611 2899338.75 None 1 dimensionless 2022-05-09 08:44:26.013419 /Users/philipps/Downloads/mmc2/
1 navis.TreeNeuron 5002989 1670 None 24 25 628291.75 None 1 dimensionless 2022-05-09 08:44:26.009716 /Users/philipps/Downloads/mmc2/
... ... ... ... ... ... ... ... ... ... ... ...
478 navis.TreeNeuron 11519759 14782 None 663 673 2714858.25 None 1 dimensionless 2022-05-09 08:44:29.017471 /Users/philipps/Downloads/mmc2/
479 navis.TreeNeuron 11543484 6256 None 367 371 1229948.00 None 1 dimensionless 2022-05-09 08:44:29.010490 /Users/philipps/Downloads/mmc2/

Let’s say you are looking at a huge collection of SWC files and you only want to sample a few of them:

# Load only the first 10 skeletons
sample = navis.read_swc('~/Downloads/mmc2/', include_subdirs=True, limit=10)
<class 'navis.core.neuronlist.NeuronList'> containing 10 neurons (1.1MiB)
type name n_nodes n_connectors n_branches n_leafs cable_length soma units created_at origin
0 navis.TreeNeuron 1313071 11634 None 600 611 2.899339e+06 None 1 dimensionless 2022-05-09 08:44:44.072213 /Users/philipps/Downloads/mmc2/
1 navis.TreeNeuron 5002989 1670 None 24 25 6.282918e+05 None 1 dimensionless 2022-05-09 08:44:44.099230 /Users/philipps/Downloads/mmc2/
... ... ... ... ... ... ... ... ... ... ... ...
8 navis.TreeNeuron 6082926 3112 None 164 171 8.933154e+05 None 1 dimensionless 2022-05-09 08:44:44.289857 /Users/philipps/Downloads/mmc2/
9 navis.TreeNeuron 2122447 2694 None 112 115 8.098385e+05 None 1 dimensionless 2022-05-09 08:44:44.312675 /Users/philipps/Downloads/mmc2/

We can also point navis.read_swc() at single files instead of folders or zip archives:

# For this I extraced the archive
s = navis.read_swc('~/Downloads/mmc2/swc/CENT/11519759.swc')
type navis.TreeNeuron
name 11519759
n_nodes 14782
n_connectors None
n_branches 663
n_leafs 673
cable_length 2714858.25
soma None
units 1 dimensionless
created_at 2022-04-14 22:01:20.455672
origin /Users/philipps/Downloads/mmc2/swc/CENT/115197...

You can even use URLs directly:

s = navis.read_swc('')

Now let’s say you have skeletons and you want to save them to disk. Easy!

# Write a single neuron
navis.write_swc(s, '~/Downloads/mmc2/my_neuron.swc')
# Write a whole list of skeletons to a folder and use the neurons' `name` property as filename
navis.write_swc(sample, '~/Downloads/mmc2/{}.swc')
# Write directly to a zip file
navis.write_swc(sample, '~/Downloads/mmc2/')
# Write directly to a zip file and use the neuron name as filename
navis.write_swc(sample, '~/Downloads/mmc2/{}')

See navis.write_swc() for further details!

NMX files

NMX is a xml-based format used e.g. by pyKNOSSOS to store skeletons (+ meta data). navis supports reading (but not writing) this format. If you want to follow along download this dataset by Wanner et al. (2016). Same procedure as with the SWCs: I extracted the archive to my downloads folder.

# Read a single file
s = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/Neuron_id0001.nmx')
type navis.TreeNeuron
name NML
id Neuron_id0001
n_nodes 3369
n_connectors None
n_branches 64
n_leafs 69
cable_length 151639.171875
soma None
units 1 dimensionless
# Read all files in folder
nl = navis.read_nmx('~/Downloads/WannerAA201605_SkeletonsGlomeruli/')
WARNING : Skipped "Glomeruli.nmx": failed to import skeleton. (navis)
<class 'navis.core.neuronlist.NeuronList'> containing 1022 neurons (142.1MiB)
type name id n_nodes n_connectors n_branches n_leafs cable_length soma units
0 navis.TreeNeuron NML Neuron_id0742 4351 None 91 96 200111.703125 None 1 dimensionless
1 navis.TreeNeuron NML Neuron_id0756 4779 None 0 3 9099.673828 None 1 dimensionless
... ... ... ... ... ... ... ... ... ... ...
1020 navis.TreeNeuron NML Neuron_id0997 2395 None 61 71 136052.546875 None 1 dimensionless
1021 navis.TreeNeuron NML Neuron_id0983 3332 None 115 123 223207.265625 None 1 dimensionless

Note the error message? NMX files don’t always contain skeletons. If navis comes across one that can’t be turned into a TreeNeuron, it will skip the file and produce a warning.

Neuroglancer precomputed format

Among other formats, neuroglancer supports a “precomputed” format for skeletons (see specs here). This binary format is more compact than uncompressed SWC files but probably is not used outside of neuroglancer afaik. That said: navis lets you read and write skeletons from/to precomputed format using navis.read_precomputed() and navis.write_precomputed(). Note that these functions work on both precomputed skeletons and meshes.

Manually constructing skeletons

What if you have some obscure data format for which navis does not have a read function? The data underlying a TreeNeuron is a simple SWC table - so as long as you can produce that from your data, you can create your own skeletons. Here’s a quick & dirty example:

import pandas as pd

# Create a mock SWC table for a 2-node skeleton
swc = pd.DataFrame()
swc['node_id'] = [0, 1]
swc['parent_id'] = [-1, 0]   # negative indices indicate roots
swc['x'] = [0, 1]
swc['y'] = [0, 1]
swc['z'] = [0, 1]
swc['radius'] = 0

node_id parent_id x y z radius
0 0 -1 0 0 0 0
1 1 0 1 1 1 0

This SWC can now be used to construct a TreeNeuron:

s = navis.TreeNeuron(swc, name='my_neuron', units='microns')
type navis.TreeNeuron
name my_neuron
n_nodes 2
n_connectors None
n_branches 0
n_leafs 1
cable_length 1.732051
soma None
units 1 micrometer

There are a few other ways to construct a navis.TreeNeuron (e.g. using a graph) - see the docstring for details.

Also note that all navis neurons can be stored to disk using pickle - see the pickling tutorial.

Hopefully the above has given you some entry points on how to load your data. See also the I/O API reference api_io>. Please keep in mind that you can also convert one neuron type into another - for example by skeletonizing MeshNeurons (see Converting neuron types).