Spaces:
Running
Running
File size: 3,827 Bytes
b200bda |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
from itertools import chain
import networkx as nx
__all__ = ["tree_data", "tree_graph"]
def tree_data(G, root, ident="id", children="children"):
"""Returns data in tree format that is suitable for JSON serialization
and use in JavaScript documents.
Parameters
----------
G : NetworkX graph
G must be an oriented tree
root : node
The root of the tree
ident : string
Attribute name for storing NetworkX-internal graph data. `ident` must
have a different value than `children`. The default is 'id'.
children : string
Attribute name for storing NetworkX-internal graph data. `children`
must have a different value than `ident`. The default is 'children'.
Returns
-------
data : dict
A dictionary with node-link formatted data.
Raises
------
NetworkXError
If `children` and `ident` attributes are identical.
Examples
--------
>>> from networkx.readwrite import json_graph
>>> G = nx.DiGraph([(1, 2)])
>>> data = json_graph.tree_data(G, root=1)
To serialize with json
>>> import json
>>> s = json.dumps(data)
Notes
-----
Node attributes are stored in this format but keys
for attributes must be strings if you want to serialize with JSON.
Graph and edge attributes are not stored.
See Also
--------
tree_graph, node_link_data, adjacency_data
"""
if G.number_of_nodes() != G.number_of_edges() + 1:
raise TypeError("G is not a tree.")
if not G.is_directed():
raise TypeError("G is not directed.")
if not nx.is_weakly_connected(G):
raise TypeError("G is not weakly connected.")
if ident == children:
raise nx.NetworkXError("The values for `id` and `children` must be different.")
def add_children(n, G):
nbrs = G[n]
if len(nbrs) == 0:
return []
children_ = []
for child in nbrs:
d = {**G.nodes[child], ident: child}
c = add_children(child, G)
if c:
d[children] = c
children_.append(d)
return children_
return {**G.nodes[root], ident: root, children: add_children(root, G)}
@nx._dispatch(graphs=None)
def tree_graph(data, ident="id", children="children"):
"""Returns graph from tree data format.
Parameters
----------
data : dict
Tree formatted graph data
ident : string
Attribute name for storing NetworkX-internal graph data. `ident` must
have a different value than `children`. The default is 'id'.
children : string
Attribute name for storing NetworkX-internal graph data. `children`
must have a different value than `ident`. The default is 'children'.
Returns
-------
G : NetworkX DiGraph
Examples
--------
>>> from networkx.readwrite import json_graph
>>> G = nx.DiGraph([(1, 2)])
>>> data = json_graph.tree_data(G, root=1)
>>> H = json_graph.tree_graph(data)
See Also
--------
tree_data, node_link_data, adjacency_data
"""
graph = nx.DiGraph()
def add_children(parent, children_):
for data in children_:
child = data[ident]
graph.add_edge(parent, child)
grandchildren = data.get(children, [])
if grandchildren:
add_children(child, grandchildren)
nodedata = {
str(k): v for k, v in data.items() if k != ident and k != children
}
graph.add_node(child, **nodedata)
root = data[ident]
children_ = data.get(children, [])
nodedata = {str(k): v for k, v in data.items() if k != ident and k != children}
graph.add_node(root, **nodedata)
add_children(root, children_)
return graph
|