用于从嵌套Python对象(字典)创建树形图的Python库
有没有人知道有什么Python库,可以简单快速地处理一个嵌套到任意层级的对象,比如说一个字典树,类似于这个链接里的内容,然后它能生成一个可以用的树形图文件?
这里的关键是简单,因为我需要和一些不太懂技术的人一起工作。
我所说的“图树”是指这样的东西,我可以把一个嵌套的字典传给它,然后它就会创建出树形结构:
(来源: rubyforge.org)
5 个回答
D3.js 是一个主要用于数据可视化的库...
据我所知,它并没有提供方便的工具来遍历图形和进行数学运算。不过,Python 的 networkX 包里有这些功能:
import networkx as nx
graph_data = {
'id': 'root',
'children': [
{
'id': 'A',
'children': [
{
'id': 'B', 'children': [{'id': 'B1'}, {'id': 'B2'}]
},
{
'id': 'C'
}
]
}
]
}
G = nx.readwrite.json_graph.tree_graph(graph_data)
print('EDGES: ', G.edges())
# EDGES: [('root', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B1'), ('B', 'B2')]
print('NODES: ', G.nodes())
# NODES: ['root', 'A', 'B', 'B1', 'B2', 'C']
这是一个从结构创建与 D3.js 相同的例子(包含 id
和 children
字段)。
图形也可以通过递归的方式逐步创建,还可以用多种格式进行读取和写入:https://networkx.github.io/documentation/stable/reference/readwrite/index.html
我不太确定这是不是你想要的,但这是我想到的第一个办法。
blockdiag 主要是用来处理文件的,类似于 Graphviz(它有Python接口)。它接受一个简单的文本文件作为输入,然后输出图像。
你可以写一个简单的程序,把你的递归字典结构转换成 blockdiag 脚本可以接受的格式,或者直接导入 blockdiag 包的必要部分,直接生成输出。
如果这个方法听起来不错,我可以试着写一些示例代码。
编辑 示例代码:
def print_blockdiag(tree, parent=None):
if not parent: print('blockdiag { orientation = portrait')
for key in tree:
if parent: print(' {} -> {};'.format(parent, key))
print_blockdiag(tree[key], key)
if not parent: print('}')
这段代码会输出一个 blockdiag 可以读取的文件。
我推荐并在这个回答中使用的库其实不是一个Python库,但它是一个对Python友好的库。我的意思是,使用这个库的代码可以插入到Python模块中进行数据处理,而这段外部代码会和现有的Python代码连接起来,无论是输入还是输出。我猜,虽然我并不确定,这就是“Python库”这个标准的真正含义。所以如果你在写一个网页应用,这段代码就是在客户端运行的。换句话说,这个库不是Python,但它可以和Python一起工作。
它的输入几乎是原始的Python字典,更具体地说,json.load(a_python_dict)会返回一个JSON数组或对象,这种格式当然是这个JavaScript库可以识别的;
输出格式要么是HTML,要么是SVG,而不是某种特定语言的对象格式。
你可以使用d3.js。它有一个专门用于渲染树形结构的类:
var tree = d3.layout.tree().size([h, w]);
在我提供的链接中,d3源代码的示例文件夹里还有几个树形结构的示例(可运行的代码)。你可以克隆或下载。
因为d3是一个JavaScript库,所以它的原生数据格式是JSON。
基本结构是一个嵌套字典,每个字典代表一个节点,包含两个值:节点的名称和它的子节点(以数组形式存储),分别用names和children作为键:
{"name": "a_root_node", "children": ["B", "C"]}
当然,Python字典和JSON之间的转换非常简单:
>>> d = {"name": 'A', "children": ['B', 'C']}
>>> import json as JSON
>>> dj = JSON.dumps(d)
>>> dj
'{"name": "A", "children": ["B", "C"]}'
这里有一个较大树形结构的Python 字典表示(大约十几个节点),我按照上面的方式转换成了JSON,然后在d3中渲染成下面图片中的树形结构:
tree = {'name': 'root', 'children': [{'name': 'node 2', 'children':
[{'name': 'node 4', 'children': [{'name': 'node 10', 'size': 7500},
{'name': 'node 11', 'size': 12000}]}, {'name': 'node 5', 'children':
[{'name': 'node 12', 'children': [{'name': 'node 16', 'size': 10000},
{'name': 'node 17', 'size': 12000}]}, {'name': 'node 13', 'size': 5000}]}]},
{'name': 'node 3', 'children': [{'name': 'node 6', 'children':
[{'name': 'node 14', 'size': 8000}, {'name': 'node 15', 'size': 9000}]},
{'name': 'node 7', 'children': [{'name': 'node 8', 'size': 10000},
{'name': 'node 9', 'size': 12000}]}]}]}
注意:d3是在浏览器中渲染的;上面的图片只是我浏览器窗口的截图。