在Python中绘制与渲染多路树
有人知道怎么把多路树画得好看一点吗?以下是一些信息:
- 大约有100个项目
- 每一层大概有相同数量的项目
- 总共有10层
- 每个节点可以有0到6个子节点
- 每个节点自己决定它所在的层级,不管它的根节点是什么。
我现在在用PIL(Python图像库),把每一“行”分成img.size()[0]
除以节点数量,然后用draw.line
画线来表示边,但结果是完全乱了
希望你们能帮帮我=],如果需要更多信息我会提供。
1 个回答
21
图形渲染是graphviz的强项,它还有几个可以和Python一起用的库。在我看来,这些库中最好的是pygraphviz。总的来说,graphviz可能是最好的解决方案,也是最简单的。
你在问题中提到的那种层次分明的布局,graphviz的dot布局引擎可以轻松实现。Dot负责渲染,确保图形呈现出自然的树形结构——也就是说,父节点在子节点的上方;同级节点(从根节点算起的层级)在y轴上尽量对齐,并且在可能的情况下保持自然的对称性。
(注意:有点让人困惑的是,dot不仅是graphviz中的一个布局引擎的名字,它还是所有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";
}