在pygraphviz/dot中以编程方式在networkx的包装器中指定相同等级的节点 [英] Programmatically specifying nodes of the same rank within networkx's wrapper for pygraphviz/dot

查看:116
本文介绍了在pygraphviz/dot中以编程方式在networkx的包装器中指定相同等级的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以更改以下代码以将Child_4放置在与Grandchild_0相同的水平位置上(从而将Grandchild_4推到其自己的水平位置)?

Is it possible to alter the following code to put Child_4 at the same horizontal level as Grandchild_0 (thereby pushing Grandchild_4 to its own level)?

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("ROOT")
for i in xrange(5):
    G.add_node("Child_%i" % i)
    G.add_node("Grandchild_%i" % i)
    G.add_edge("ROOT", "Child_%i" % i)
    G.add_edge("Child_%i" % i, "Grandchild_%i" % i)

pos=nx.graphviz_layout(G,prog='dot')
nx.draw(G,pos,arrows=False)
plt.show()

上面的代码产生以下布局,我想通过将子级向下移动一级使其与孙子级水平对齐来进行更改:

The above code produces the following layout, which I'd like to alter by shifting a child down one level to be horizontally aligned with the grandchildren:

在Python网络库networkx中,我正在使用graphviz的点引擎来渲染树(以下

Within the Python network library networkx, I'm using graphviz's dot engine to render a tree (following this recommendation). I would like to control the y-position of the nodes by specifying which nodes should have the same height. The nodes might be at different depths in the tree.

我知道,如果我使用rank=same命令(例如,{rank=same; n4 -> p2;} []来生成节点位置,和graphviz_layout只能将命令行参数发送到pygraphviz.我尝试使用nx.graphviz_layout(G, prog='dot', args="-Grank=same; n4 -> p2;")的变体失败. 是否可以在pygraphviz的NetworkX包装器中描述所需的节点高度,还是我需要围绕pygraphviz编写自己的包装器? 答案提供了新的包装器在pygraphviz周围.这将大大简化在pygraphviz的现有NetworkX包装器中发送等级信息的过程.如果有人可以告诉我这怎么可能,我将更改接受的答案.

I know I could control the node height if I wrote my own graphviz code through using the rank=same command (e.g., {rank=same; n4 -> p2;} [ex.]). However, I am relying on networkx.graphviz_layout() [doc | source] to generate the node positions, and graphviz_layout can send only command line arguments to pygraphviz. My attempts to use variants of nx.graphviz_layout(G, prog='dot', args="-Grank=same; n4 -> p2;") have failed. Is it possible to describe the desired node heights within the NetworkX wrapper for pygraphviz, or do I need to write my own wrapper around pygraphviz? The answer provides a new wrapper around pygraphviz. It would significantly simplify things to send the rank information within the existing NetworkX wrapper for pygraphviz. I'll change my accepted answer if someone can tell me how that might be possible.

推荐答案

我找不到通过原始networkx包装器实现此目标的方法.

I can't find a way to achieve this through the original networkx wrapper.

相反,我为pygraphviz编写了新的包装程序,其中大部分行从的调用添加一个for循环.

Instead, I've written a new wrapper for pygraphviz, with most lines copied from the source code. It adds a parameter sameRank = [] for a list of nodes-of-the-same-rank lists and a for loop around an invocation of pygraphviz.add_subgraph(listOfNodes,rank="same").

def graphviz_layout_with_rank(G, prog = "neato", root = None, sameRank = [], args = ""):
    ## See original import of pygraphviz in try-except block
    ## See original identification of root through command line
    A = nx.to_agraph(G)
    for sameNodeHeight in sameRank:
        if type(sameNodeHeight) == str:
            print("node \"%s\" has no peers in its rank group" %sameNodeHeight)
        A.add_subgraph(sameNodeHeight, rank="same")
    A.layout(prog=prog, args=args)
    ## See original saving of each node location to node_pos 
    return node_pos

在问题示例中,可以通过以下行将Child_4推到与Grandchild_0相同的水平位置:

In the question example, Child_4 can be pushed to the same horizontal level as Grandchild_0 through the line:

pos=graphviz_layout_with_rank(G, prog='dot',sameRank=[["Child_4","Grandchild_0"]])

这篇关于在pygraphviz/dot中以编程方式在networkx的包装器中指定相同等级的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆