Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
274 views
in Technique[技术] by (71.8m points)

python - Pygraphviz / networkx set node level or layer

I have a dataset that represents a kind of genealogy tree. Each node has 2 parents (except first generation, they have no parents). For a given node, its parents can be from any previous generation. For example a node in generation n, can have a parent in n-1, and another parent in n-5. A node can be parent of several other nodes.

So basically, for every node I know its generation and its parents.

I am trying to represent this graph keeping the nodes from the same generation in the same line. Each generation has 10 nodes, except the first one.

So far I am trying the "dot" layout. When I only input two generations it does a good job, but when I input 3 generations, it is "too smart", and rearranges the nodes in some way.

For example, the following data, which represents 3 generations:

[(ObjectId('530b2ad783a1a15e695c9711'), ObjectId('530b804883a1a15e695c972b')), (ObjectId('530b2ad783a1a15e695c971c'), ObjectId('530b804883a1a15e695c972b')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530b804883a1a15e695c9727')), (ObjectId('530b2ad783a1a15e695c970a'), ObjectId('530b804883a1a15e695c9727')), (ObjectId('530b2ad783a1a15e695c970b'), ObjectId('530b804883a1a15e695c9724')), (ObjectId('530b2ad783a1a15e695c970f'), ObjectId('530b804883a1a15e695c9724')), (ObjectId('530b2ad783a1a15e695c9714'), ObjectId('530b804883a1a15e695c9729')), (ObjectId('530b2ad783a1a15e695c970e'), ObjectId('530b804883a1a15e695c9729')), (ObjectId('530b2ad783a1a15e695c9711'), ObjectId('530b804883a1a15e695c9723')), (ObjectId('530b2ad783a1a15e695c970e'), ObjectId('530b804883a1a15e695c9723')), (ObjectId('530b2ad783a1a15e695c971c'), ObjectId('530b804883a1a15e695c9728')), (ObjectId('530b2ad783a1a15e695c9719'), ObjectId('530b804883a1a15e695c9728')), (ObjectId('530b2ad783a1a15e695c9714'), ObjectId('530b804883a1a15e695c9726')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530b804883a1a15e695c9726')), (ObjectId('530b2ad783a1a15e695c9716'), ObjectId('530b804883a1a15e695c9722')), (ObjectId('530b2ad783a1a15e695c9719'), ObjectId('530b804883a1a15e695c9722')), (ObjectId('530b2ad783a1a15e695c970d'), ObjectId('530b804883a1a15e695c9725')), (ObjectId('530b2ad783a1a15e695c9715'), ObjectId('530b804883a1a15e695c9725')), (ObjectId('530b804883a1a15e695c9724'), ObjectId('530ba27c83a1a15e695c972d')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530ba27c83a1a15e695c972d')), (ObjectId('530b804883a1a15e695c9724'), ObjectId('530ba27c83a1a15e695c972e')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530ba27c83a1a15e695c972e')), (ObjectId('530b804883a1a15e695c9727'), ObjectId('530ba27c83a1a15e695c972f')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530ba27c83a1a15e695c972f')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530ba27c83a1a15e695c9730')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530ba27c83a1a15e695c9730')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530ba27c83a1a15e695c9731')), (ObjectId('530b804883a1a15e695c9725'), ObjectId('530ba27c83a1a15e695c9731')), (ObjectId('530b804883a1a15e695c9722'), ObjectId('530ba27c83a1a15e695c9732')), (ObjectId('530b2ad783a1a15e695c970b'), ObjectId('530ba27c83a1a15e695c9732')), (ObjectId('530b2ad783a1a15e695c9711'), ObjectId('530ba27c83a1a15e695c9733')), (ObjectId('530b2ad783a1a15e695c971f'), ObjectId('530ba27c83a1a15e695c9733')), (ObjectId('530b804883a1a15e695c972b'), ObjectId('530ba27c83a1a15e695c9734')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530ba27c83a1a15e695c9734')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530ba27c83a1a15e695c9735')), (ObjectId('530b804883a1a15e695c9724'), ObjectId('530ba27c83a1a15e695c9735')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530ba27c83a1a15e695c9736')), (ObjectId('530b804883a1a15e695c9723'), ObjectId('530ba27c83a1a15e695c9736')), (ObjectId('530b2ad783a1a15e695c9716'), ObjectId('530b804883a1a15e695c9722')), (ObjectId('530b2ad783a1a15e695c9719'), ObjectId('530b804883a1a15e695c9722')), (ObjectId('530b2ad783a1a15e695c9711'), ObjectId('530b804883a1a15e695c9723')), (ObjectId('530b2ad783a1a15e695c970e'), ObjectId('530b804883a1a15e695c9723')), (ObjectId('530b2ad783a1a15e695c970b'), ObjectId('530b804883a1a15e695c9724')), (ObjectId('530b2ad783a1a15e695c970f'), ObjectId('530b804883a1a15e695c9724')), (ObjectId('530b2ad783a1a15e695c970d'), ObjectId('530b804883a1a15e695c9725')), (ObjectId('530b2ad783a1a15e695c9715'), ObjectId('530b804883a1a15e695c9725')), (ObjectId('530b2ad783a1a15e695c9714'), ObjectId('530b804883a1a15e695c9726')), (ObjectId('530b2ad783a1a15e695c9713'), ObjectId('530b804883a1a15e695c9726')), (ObjectId('530b2ad783a1a15e695c9709'), ObjectId('530b804883a1a15e695c9727')), (ObjectId('530b2ad783a1a15e695c970a'), ObjectId('530b804883a1a15e695c9727')), (ObjectId('530b2ad783a1a15e695c971c'), ObjectId('530b804883a1a15e695c9728')), (ObjectId('530b2ad783a1a15e695c9719'), ObjectId('530b804883a1a15e695c9728')), (ObjectId('530b2ad783a1a15e695c9714'), ObjectId('530b804883a1a15e695c9729')), (ObjectId('530b2ad783a1a15e695c970e'), ObjectId('530b804883a1a15e695c9729')), (ObjectId('530b2ad783a1a15e695c9715'), ObjectId('530b804883a1a15e695c972a')), (ObjectId('530b2ad783a1a15e695c970b'), ObjectId('530b804883a1a15e695c972a')), (ObjectId('530b2ad783a1a15e695c9711'), ObjectId('530b804883a1a15e695c972b')), (ObjectId('530b2ad783a1a15e695c971c'), ObjectId('530b804883a1a15e695c972b'))]

produces:enter image description here

All the nodes that are "root" and therefore don't receive an edge should be placed on the first line, for example, but it is placing some of them on the second level.

Once I try to make bigger graphs, with 10 generations, all the hierarchy makes no sense at all.

is there any parameter or way to specify the level or layer of a node? In the data I provided that info is not there, but I can easily produce it, the problem is that I don't know how to send that info to pygraphviz or networkx.

I also want to use this data to produce graphs with twopi like this one http://networkx.github.io/documentation/latest/examples/drawing/lanl_routes.html

where the layers are represented on a circular way.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use a Graphviz subgraph with attribute rank=same. e.g.

import networkx as nx
import pygraphviz as pgv # pygraphviz should be available

G = nx.DiGraph()
G.add_edge('a','aa')
G.add_edge('a','ab')
G.add_edge('a','bbc')
G.add_edge('b','ab')
G.add_edge('b','bb')
G.add_edge('c','bbc')
G.add_edge('bb','bba')
G.add_edge('bb','bbc')
A = nx.to_agraph(G)
one = A.add_subgraph(['a','b','c'],rank='same')
two = A.add_subgraph(['aa','ab','bb'],rank='same')
three = A.add_subgraph(['bba','bbc'],rank='same')
A.draw('example.png', prog='dot')

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...