简体   繁体   English

在 Python 中绘制和渲染多路树

[英]Drawing & Rendering Multiway Tree in Python

Does somebody know how do I plot a multiway-tree in a aesthetically plausible way?有人知道我如何以美观合理的方式 plot 多路树吗? info:信息:

  • more or less 100 items或多或少 100 个项目
  • each level have approximately the same number of items每个级别都有大约相同数量的项目
  • 10 levels 10级
  • each node have between 0(leaf) and 6 childs每个节点有 0(叶)到 6 个子节点
  • each node specify it's own level, no matter his roots.每个节点都指定它自己的级别,不管他的根。

I'm currently using PIL, dividing each "line" in img.size()[0] /number of nodes, and drawing lines with draw.line to represent edges, but it is completely messed up我目前正在使用PIL,将img.size()[0] /节点数中的每个“线”划分,并用draw.line画线来表示边缘,但它完全搞砸了

I hope you can help me =], any information needed I'll post.我希望你能帮助我=],我会发布任何需要的信息。

So, rendering graphs is the particular genius of graphviz , which also happens to have several libraries that provide python bindings.因此,渲染图是graphviz的独特之处,它也恰好有几个提供 python 绑定的库。 In my opinion, the best of these bindings libraries is pygraphviz .在我看来,这些绑定库中最好的是pygraphviz Graphviz is probably the best solution and also likely the simplest. Graphviz 可能是最好的解决方案,也可能是最简单的解决方案。

The particular layout you describe in your Question, a hierarchical, layered scheme, is performed effortlessly by graphviz' dot layout engine.您在问题中描述的特定布局是一种分层的分层方案,由 graphviz 的布局引擎轻松执行。 Dot performs the rendering to ensure that the graph is laid out in a natural tree configuration--ie, parent nodes are positioned above their children; Dot执行渲染以确保图形以自然树配置布局 - 即,父节点位于其子节点之上; nodes of equal rank (levels from the root) are equi-positioned w/r/t the y-axis when possible, and natural symmetry is preserved when possible.相同等级的节点(从根开始的级别)尽可能在 y 轴上等位,并尽可能保持自然对称性。

(Note: confusingly, dot refers to one of several layout engines that comprise graphviz , but dot is also the name and file extension of the file format for all graphviz documents regardless of how they are rendered). (注意:令人困惑的是, dot指的是组成graphviz的几个布局引擎之一,但dot也是所有 graphviz 文档的文件格式的名称和文件扩展名,无论它们如何呈现)。

As you can see in my code that follows, using pygraphviz, it's simple to select dot as layout engine for your graph, though it's not actually the default ( neato is).正如您在下面的代码中看到的那样,使用 pygraphviz,将 select作为图形的布局引擎很简单,尽管它实际上不是默认设置( neato是)。

Here's a quick graph i made and then rendered using dot --created and rendered using graphviz via pygraphviz .这是我制作的快速图表,然后使用dot --created 渲染并通过pygraphviz使用graphviz渲染。

Notice that the graph has perfect layout--nodes of the same degree are on the same level along a vertical axis, children are rendered below parents and natural 'symmetry' is preserved when possible (eg, a parent node is positioned between and above its two child nodes. And as you can see, none of my code manually controls the layout--graphviz, ie, dot , handles it automatically.请注意,该图具有完美的布局——相同程度的节点沿垂直轴处于同一水平,子节点呈现在父节点下方,并且尽可能保留自然的“对称性”(例如,父节点位于其之间和上方两个子节点。如您所见,我的代码都没有手动控制布局——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";
}

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM