2012-05-05 146 views
-1

我拼命寻找解决方案来创建一个不错的二叉树图。不完整的节点具有可区分的边缘(如果有的话)是至关重要的。从嵌套列表创建.graphml树图

我无法用.dot产生所需的结果,因为我知道无法排序节点。我不介意将文件导入yEd或其他编辑器。但是,我希望能够用很少的语法很容易地生成数据。

我想要的是一种工具,它可以生成例如例如(A(B1 C1 C2)B2)这样的简单数据的.graphml格式,其中A是根标签,B1是根的左边孩子和另外两个孩子。与.dot或.tgf类似的复杂性当然是可以忍受的,但我想避免编写一个编译器来生成.graphml。

任何想法赞赏。

马库斯R.

+0

这是什么意思_This只适用于.dot空节点_? – marapet

+0

也就是说,我必须使用不可见的虚拟节点(叶子)来指引边缘。 –

+0

在可视化图形中,为什么要避免使用虚拟节点? – parselmouth

回答

1

您提供的数据是更多或更少的s-expression。鉴于这是你想要获取的格式,pyparsing(一个Python模块)有一个s-expression parser

您还需要一个图库。我的大部分工作都使用networkx。随着pyparsing s表达式解析器和networkx,下面的代码提取数据,并创建一个树作为一个有向图:

import networkx as nx 

def build(g, X): 
    if isinstance(X, list): 
     parent = X[0] 
     g.add_node(parent) 
     for branch in X[1:]: 
      child = build(g, branch) 
      g.add_edge(parent, child) 

     return parent 

    if isinstance(X, basestring): 
     g.add_node(X) 
     return X 

#-- The sexp parser is constructed by the code example at... 
#-- http://http://pyparsing.wikispaces.com/file/view/sexpParser.py 
sexpr = sexp.parseString("(A (B1 C1 C2) B2)", parseAll = True) 

#-- Get the parsing results as a list of component lists. 
nested = sexpr.asList() 

#-- Construct an empty digraph. 
dig = nx.DiGraph() 

#-- build the tree 
for component in nested: 
    build(dig, component) 

#-- Write out the tree as a graphml file. 
nx.write_graphml(dig, 'tree.graphml', prettyprint = True) 

为了验证这一点,我也写了树作为.DOT文件,并使用graphviz的创建下面的图片:

(graphviz output of tree)

networkx是一个很好的图形库,你可以写走到你的树,如果需要额外的元数据标记边缘或节点,额外的代码。

+0

谢谢。我不知道networkx库。但是,结果并不是我所需要的。在你的例子中,如果你删除,让我们说C2,然后在生成的新图像,你将有一条从B1到C1的垂直线,因此不再有任何迹象表明C1是一个正确的孩子(和B1没有离开孩子) 。我需要的是一张图片,它维持着这个结构。无论如何,解析器都非常有用。 –

+0

@MarkusRother如果“(A(B1 C1 C2)B2)”描述了当前的树,那么在C2被删除的情况下,您能否提供类似的嵌套结构?如果新的嵌套结构被表示为“(A(B1 C1)B2)” - 我们如何区分C1是B1的正确孩子而不是左侧孩子? – parselmouth

+0

@MarkusRother通过阅读您以前的评论,“垂直”这个词很突出,并且结合您对“无形虚拟节点(叶子)引导边缘”问题的评论,是您的问题的根本之一,嵌套结构,还是(可能)不完整的树的布局和可视化? – parselmouth