Pergunta

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.

Foi útil?

Solução

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

Outras dicas

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

this link will help you. rank_same.py

import graphviz

d = graphviz.Digraph(filename='rank_same.gv')

with d.subgraph() as s:
    s.attr(rank='same')
    s.node('A')
    s.node('X')

d.node('C')

with d.subgraph() as s:
    s.attr(rank='same')
    s.node('B')
    s.node('D')
    s.node('Y')

d.edges(['AB', 'AC', 'CD', 'XY'])

d.view()

enter image description here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top