【问题标题】:Drawing & Rendering Multiway Tree in Python在 Python 中绘制和渲染多路树
【发布时间】:2011-08-11 04:11:40
【问题描述】:

有人知道我如何以美观合理的方式绘制多路树吗? 信息:

  • 大约 100 项
  • 每个级别的项目数量大致相同
  • 10 级
  • 每个节点有 0(叶)到 6 个子节点
  • 每个节点都指定它自己的级别,不管他的根。

我目前正在使用PIL,将每个“线”划分为img.size()[0]/节点数,并用draw.line画线表示边缘,但它完全搞砸了

我希望你能帮助我=],任何需要的信息我都会发布。

【问题讨论】:

    标签: python graph tree graphviz multiway-tree


    【解决方案1】:

    因此,渲染图是graphviz 的独特之处,它也恰好有几个提供 python 绑定的库。在我看来,这些绑定库中最好的是pygraphviz。 Graphviz 可能是最好的解决方案,也可能是最简单的解决方案。

    您在问题中描述的特定布局是一种分层的分层方案,由 graphviz 的 dot 布局引擎轻松执行。 Dot 执行渲染以确保图形以自然树配置布局 - 即,父节点位于其子节点之上;相同等级的节点(从根开始的级别)尽可能在 y 轴上等位,并尽可能保持自然对称性。

    (注意:令人困惑的是,dot 是指组成 graphviz 的几个布局引擎之一,但 dot 也是名称和文件扩展名所有graphviz文档的文件格式,无论它们如何呈现)。

    正如您在下面的代码中看到的那样,使用 pygraphviz,选择 dot 作为图形的布局引擎很简单,尽管它实际上不是默认设置 (neato是)。

    这是我制作的快速图表,然后使用 dot 进行渲染——通过 pygraphviz 使用 graphviz 创建和渲染。

    请注意,该图具有完美的布局——相同度数的节点沿垂直轴处于同一水平,子节点呈现在父节点下方,并且尽可能保留自然“对称性”(例如,父节点位于在它的两个子节点之上。正如你所看到的,我的代码都没有手动控制布局——graphviz,即dot,自动处理它。

    import pygraphviz as PG
    
    A = PG.AGraph(directed=True, strict=True)
    
    A.add_edge("7th Edition", "32V")
    A.add_edge("7th Edition", "Xenix")
    # etc., etc.
    
    # save the graph in dot format
    A.write('ademo.dot')
    
    # pygraphviz renders graphs in neato by default, 
    # so you need to specify dot as the layout engine
    A.layout(prog='dot')
    
    
    # opening the dot file in a text editor shows the graph's syntax:
    digraph unix {
      size="7,5";
      node [color=goldenrod2, style=filled];
      "7th Edition" -> "32V";
      "7th Edition" -> "V7M";
      "7th Edition" -> "Xenix";
      "7th Edition" -> "UniPlus+";
      "V7M" -> "Ultrix-11";
      "8th Edition" -> "9th Edition";
      "1 BSD" -> "2 BSD";
      "2 BSD" -> "2.8 BSD";
      "2.8 BSD" -> "Ultrix-11";
      "2.8 BSD" -> "2.9 BSD";
      "32V" -> "3 BSD";
      "3 BSD" -> "4 BSD";
      "4 BSD" -> "4.1 BSD";
      "4.1 BSD" -> "4.2 BSD";
      "4.1 BSD" -> "2.8 BSD";
      "4.1 BSD" -> "8th Edition";
      "4.2 BSD" -> "4.3 BSD";
      "4.2 BSD" -> "Ultrix-32";
    }
    

    【讨论】:

    • 完美,我只需要优化布局、颜色、耶稣的血...谢谢。 =]
    • @doug,你能告诉我如何使用参数设置节点级别(行)吗?只是为了美观。
    • @BrainStorm:好吧,dot 通常会在没有任何额外配置的情况下解决这个问题。强制这个节点配置——设置一个明确的约束——并不难,但需要两个步骤:(i)定义一个“子图”(图中的节点组具有相同的水平位置); (ii) 在子图定义中,设置“rank”属性,如下所示:rank=same。 cmets 中的空间不足,无法进一步解释子图,但此页面给出了简单的示例:graphviz.org/content/cluster
    • Dot (Graphviz) 有一个地方落伍了:如果你想有某种排序除了拓扑,你必须真正破解它。例如,如果要绘制二叉树,则哪个子节点向左哪个向右很重要。您可以使用子图、不可见边、rank=same 约束来实现这一点……但这并不漂亮。
    • pygraphviz 无法在 Windows 上安装。我最终使用了 pydot。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 1970-01-01
    • 2022-01-12
    • 2015-06-06
    • 2016-06-17
    • 2014-08-16
    • 2011-01-10
    相关资源
    最近更新 更多