Drawing & Rendering Multiway Tree in Python

眉间皱痕 提交于 2019-11-30 06:57:49

So, rendering graphs is the particular genius of graphviz, which also happens to have several libraries that provide python bindings. In my opinion, the best of these bindings libraries is pygraphviz. Graphviz is probably the best solution and also likely the simplest.

The particular layout you describe in your Question, a hierarchical, layered scheme, is performed effortlessly by graphviz' dot layout engine. Dot performs the rendering to ensure that the graph is laid out in a natural tree configuration--i.e., parent nodes are positioned above their children; 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.

(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).

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).

Here's a quick graph i made and then rendered using dot--created and rendered using graphviz via pygraphviz.

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 (e.g., 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, i.e., dot, handles it automatically.

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";
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!