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

Skeleton to a networkx graph conversion #19

Closed
venugovh opened this issue Oct 28, 2021 · 8 comments
Closed

Skeleton to a networkx graph conversion #19

venugovh opened this issue Oct 28, 2021 · 8 comments

Comments

@venugovh
Copy link

Hi @schlegelp !

I am trying to convert a skeleton to a networkx graph upon which I can then use many graph-based algorithms such as shortest path (by assigning the distance between nodes as edge-weights), etc.

Before, I dig deep into this, I wanted to know if this is already done or is there a straightforward way within skeletor to convert a skeleton to a networkx graph? Any input will be very helpful.

I am really enjoying this library by the way!

Thanks!

@schlegelp
Copy link
Collaborator

schlegelp commented Oct 28, 2021

Yeah. Each skeleton has a .graph property that holds the networkx graph representation of the neuron:

>>> n = navis.example_neurons()
>>> n.graph
<networkx.classes.digraph.DiGraph at 0x162849f10>

It is automatically regenerated when the neuron is changed. The distance between nodes is used as weights:

>>> n.graph.edges[(2, 1)]  
{'weight': 34.64101615137755}

There are also explicit methods to (re-)generate the graph:

>>> n.get_graph_nx()
<networkx.classes.digraph.DiGraph at 0x1474c4050>
>>> navis.neuron2nx(n)
<networkx.classes.digraph.DiGraph at 0x162a5bf50>

For the record: the same exists for igraph as .igraph property, get_igraph() method and navis.neuron2igraph function.

@venugovh
Copy link
Author

omg, this is a lifesaver! Thank you very much for the quick response!

@venugovh
Copy link
Author

@schlegelp Sorry I closed this issue prematurely! I am able to see the graph in myskeleton.skeleton.vertex_graph. But when I called .edges[(a, b)], I am getting an attribute entity_index: 0 in the dict. I am looking for the node distance values as you mentioned.
Just a pre-cursor, I have an stl file read in trimesh and generated the skeleton using the wavefront method.
Am I missing something here?
Thanks!

@venugovh venugovh reopened this Oct 28, 2021
@schlegelp
Copy link
Collaborator

Can you give a minimal code example? I have no clue what myskeleton.skeleton.vertex_graph is supposed to be.

@venugovh
Copy link
Author

Sure, so sorry for the ambiguity!

import trimesh
import skeletor
mesh= trimesh.load_mesh('u_bend.stl')
skeleton = skeletor.skeletonize.by_wavefront(mesh, waves=1)
skeleton.show(mesh=True)
G = skeleton.skeleton.vertex_graph
print(G.edges[(1, 0)])

The STL file can be downloaded from:

https://drive.google.com/file/d/1YzNwCBoZ4l0L7E_ht0NOMVXqsSiG7PgR/view?usp=sharing

Thank you!

@schlegelp
Copy link
Collaborator

schlegelp commented Oct 29, 2021

skeletor is totally independent of navis. That's on purpose to keep skeletor comparatively light-weight.
Your skeleton is an instance of the skeletor.Skeleton class which is not the same as a navis.TreeNeuron. The skeleton.skeleton is actually a trimesh.Path object cached for plotting. It just so happens that it to also provides a graph representation but it apparently does not hold distances as edge weight.

Bottom line: you have to convert your skeletor.Skeleton to a navis.TreeNeuron if you want to follow the example I laid out above. Fortunately that's very simple:

n = navis.TreeNeuron(skeleton.swc)
G = n.graph

G will hold the distance between nodes as edges. That said: not having looked at your mesh, you might not have an edge (1, 0) in your skeleton.

@schlegelp
Copy link
Collaborator

schlegelp commented Oct 29, 2021

Apologies: I just realised that I misread your earlier question/thought I was in a different repo 🤦 (in my defence: it was fairly late in the evening).

To clarify: I'm talking about navis which I typically use to further process skeletons. So what I am recommending is install navis and then do this:

import navis
n = navis.TreeNeuron(skeleton.swc)
G = n.graph

@venugovh
Copy link
Author

Thank you for the clarification.

Apologies: I just realised that I misread your earlier question/thought I was in a different repo 🤦

To clarify: I'm talking about navis which I typically use to further process skeletons.

No problem, thank you for the help! I will be sure to check out navis!

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

No branches or pull requests

2 participants