在Python中绘制与渲染多路树

13 投票
1 回答
20788 浏览
提问于 2025-04-16 23:21

有人知道怎么把多路树画得好看一点吗?以下是一些信息:

  • 大约有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";
}

enter image description here

撰写回答