Pygraphviz / networkx set node level or layer

旧街凉风 提交于 2019-12-17 19:30:14

问题


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:

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.


回答1:


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')




回答2:


As of 2017, the function to_agraph is no longer exposed at the nx.level. Now you must call nx.nx_agraph.to_agraph()



来源:https://stackoverflow.com/questions/22207802/pygraphviz-networkx-set-node-level-or-layer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!