您可以通过三个步骤来完成此操作:
- 递归构造一个嵌套字典,表示 Scipy 返回的树to_tree http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.to_tree.html#scipy.cluster.hierarchy.to_tree method.
- 迭代嵌套字典,用其子树中的叶子标记每个内部节点。
-
dump http://docs.python.org/2/library/json.html#json.dump将生成的嵌套字典转换为 JSON 并加载到 d3 中。
构建表示树状图的嵌套字典
第一步,拨打电话很重要to_tree
with rd=False
以便返回树状图的根。从该根开始,您可以构造嵌套字典,如下所示:
# Create a nested dictionary from the ClusterNode's returned by SciPy
def add_node(node, parent ):
# First create the new node and append it to its parent's children
newNode = dict( node_id=node.id, children=[] )
parent["children"].append( newNode )
# Recursively add the current node's children
if node.left: add_node( node.left, newNode )
if node.right: add_node( node.right, newNode )
T = scipy.cluster.hierarchy.to_tree( clusters , rd=False )
d3Dendro = dict(children=[], name="Root1")
add_node( T, d3Dendro )
# Output: => {'name': 'Root1', 'children': [{'node_id': 10, 'children': [{'node_id': 1, 'children': []}, {'node_id': 9, 'children': [{'node_id': 6, 'children': [{'node_id': 0, 'children': []}, {'node_id': 2, 'children': []}]}, {'node_id': 8, 'children': [{'node_id': 5, 'children': []}, {'node_id': 7, 'children': [{'node_id': 3, 'children': []}, {'node_id': 4, 'children': []}]}]}]}]}]}
基本思想是从不在树状图中的节点开始,该节点将充当整个树状图的根。然后我们递归地将左子节点和右子节点添加到这个字典中,直到到达叶子。此时,我们还没有节点的标签,因此我只是通过节点的 clusterNode ID 来标记节点。
标记树状图
接下来,我们需要使用 node_ids 来标记树状图。这些评论应该足以解释它是如何工作的。
# Label each node with the names of each leaf in its subtree
def label_tree( n ):
# If the node is a leaf, then we have its name
if len(n["children"]) == 0:
leafNames = [ id2name[n["node_id"]] ]
# If not, flatten all the leaves in the node's subtree
else:
leafNames = reduce(lambda ls, c: ls + label_tree(c), n["children"], [])
# Delete the node id since we don't need it anymore and
# it makes for cleaner JSON
del n["node_id"]
# Labeling convention: "-"-separated leaf names
n["name"] = name = "-".join(sorted(map(str, leafNames)))
return leafNames
label_tree( d3Dendro["children"][0] )
转储为 JSON 并加载到 D3 中
最后,在树状图被标记后,我们只需将其输出为 JSON 并加载到 D3 中。为了完整起见,我只是在此处粘贴 Python 代码以将其转储为 JSON。
# Output to JSON
json.dump(d3Dendro, open("d3-dendrogram.json", "w"), sort_keys=True, indent=4)
Output
我创建了下面的树状图的 Scipy 和 D3 版本。对于 D3 版本,我只需插入我输出的 JSON 文件('d3-dendrogram.json'
)进入这个Gist http://bl.ocks.org/mbostock/4063570.
SciPy 树状图
D3 树状图