【问题标题】:How do I add edges between two subgraphs in pydot?如何在 pydot 中的两个子图之间添加边?
【发布时间】:2020-02-27 22:37:14
【问题描述】:

有人知道如何在 pydot 中的两个子图(簇)之间添加边吗?

callgraph = pydot.Dot(graph_type='digraph',fontname="Verdana")
cluster_foo=pydot.Cluster('foo',label='foo')
cluster_foo.add_node(pydot.Node('foo_method_1',label='method_1'))
callgraph.add_subgraph(cluster_foo)

cluster_bar=pydot.Cluster('bar',label='Component1')
cluster_bar.add_node(pydot.Node('bar_method_a'))
callgraph.add_subgraph(cluster_bar)

我试过了:

callgraph.add_edge(pydot.Edge("foo","bar"))

但不起作用。它只是在初始图中再创建两个标记为“foo”和“bar”的节点,并在它们之间放置一条边!

有人可以帮忙吗?

【问题讨论】:

    标签: python graph graphviz edges pydot


    【解决方案1】:
    • Graphviz 要求边位于 2 个集群中的 节点 之间。
    • 添加图形参数 Compound='true'。
    • 使用边缘参数 lhead= 和 ltail=。

    所以你的代码会变成:

    callgraph = pydot.Dot(graph_type='digraph', fontname="Verdana", compound='true')
    
    
    cluster_foo=pydot.Cluster('foo',label='foo')
    callgraph.add_subgraph(cluster_foo)
    
    node_foo = pydot.Node('foo_method_1',label='method_1')
    cluster_foo.add_node(node_foo)
    
    
    cluster_bar=pydot.Cluster('bar',label='Component1')
    callgraph.add_subgraph(cluster_bar)
    
    node_bar = pydot.Node('bar_method_a')
    cluster_bar.add_node(node_bar)
    
    
    callgraph.add_edge(pydot.Edge(node_foo, node_bar, ltail=cluster_foo.get_name(), lhead=cluster_bar.get_name()))
    

    【讨论】:

    • Edge() 调用似乎有点不正确:它采用边缘名称 foo_method_1bar_method_a,而不是节点实例。当 pydot 尝试转换为点文件时,您的版本将导致未处理的运行时错误。
    • 事实证明,pydot 在这个主题上的文档记录略显不足。没错,pydot.Edge() 文档字符串将其描述为采用纯节点名称字符串,根本没有提及 pydot.Node 对象。然而,实际的Edge 类确实包含接受Node 对象作为纯字符串替代的代码。处理它们的 pydot.py 中的相关代码是:if isinstance(src, Node): src = src.get_name() if isinstance(dst, Node): dst = dst.get_name() 所以,上面的答案代码确实起作用了。 (当时它已经过测试,现在再次测试只是为了确保。)
    • 总的来说,我对不超出 API 文档所做的承诺非常严格,所以:感谢您注意到这一点并大声疾呼!也就是说,在这种特定情况下,我很确定它只是缺少一点文档,并且 pydot 对Edge(Node(...)) 的支持是官方预期的稳定功能。例如,否则 Edge()Graph.add_node() 会产生令人困惑的冲突调用约定。并且“pydot 示例”的 2 个 Google 热门点击实际上都使用了 pydot 的这一特性。
    • 在我的情况下它不受支持,即它在我写的时候给出了运行时异常 - 这可能与我正在使用的 pydot 版本有关:1.0.28。你有哪一个(pip freeze | grep pydot)?
    • 早在 2011 年,我可能使用 1.0.2 或 1.0.4 进行了测试。刚才我用 Ubuntu 15.04 的 python-pydot 包进行了测试,它是 1.0.28。据 Github 介绍,该功能是在 1.0.2 中引入的:github.com/erocarrera/pydot/commit/…。当我用 pip 测试它时:virtualenv test-pydot-B; source test-pydot-B/bin/activate; pip install pydot; pip freeze 我得到pydot==1.0.2。通过该路径安装软件包时,该功能也可以使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2014-05-19
    • 2021-03-23
    • 1970-01-01
    • 2021-06-05
    • 2019-07-26
    相关资源
    最近更新 更多