Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/readwrite/json_graph/node_link.py: 18%
44 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
1from itertools import chain, count
3import networkx as nx
5__all__ = ["node_link_data", "node_link_graph"]
8_attrs = {
9 "source": "source",
10 "target": "target",
11 "name": "id",
12 "key": "key",
13 "link": "links",
14}
17def _to_tuple(x):
18 """Converts lists to tuples, including nested lists.
20 All other non-list inputs are passed through unmodified. This function is
21 intended to be used to convert potentially nested lists from json files
22 into valid nodes.
24 Examples
25 --------
26 >>> _to_tuple([1, 2, [3, 4]])
27 (1, 2, (3, 4))
28 """
29 if not isinstance(x, (tuple, list)):
30 return x
31 return tuple(map(_to_tuple, x))
34def node_link_data(
35 G,
36 *,
37 source="source",
38 target="target",
39 name="id",
40 key="key",
41 link="links",
42):
43 """Returns data in node-link format that is suitable for JSON serialization
44 and use in JavaScript documents.
46 Parameters
47 ----------
48 G : NetworkX graph
49 source : string
50 A string that provides the 'source' attribute name for storing NetworkX-internal graph data.
51 target : string
52 A string that provides the 'target' attribute name for storing NetworkX-internal graph data.
53 name : string
54 A string that provides the 'name' attribute name for storing NetworkX-internal graph data.
55 key : string
56 A string that provides the 'key' attribute name for storing NetworkX-internal graph data.
57 link : string
58 A string that provides the 'link' attribute name for storing NetworkX-internal graph data.
60 Returns
61 -------
62 data : dict
63 A dictionary with node-link formatted data.
65 Raises
66 ------
67 NetworkXError
68 If the values of 'source', 'target' and 'key' are not unique.
70 Examples
71 --------
72 >>> G = nx.Graph([("A", "B")])
73 >>> data1 = nx.node_link_data(G)
74 >>> data1
75 {'directed': False, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 'A'}, {'id': 'B'}], 'links': [{'source': 'A', 'target': 'B'}]}
77 To serialize with JSON
79 >>> import json
80 >>> s1 = json.dumps(data1)
81 >>> s1
82 '{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, {"id": "B"}], "links": [{"source": "A", "target": "B"}]}'
84 A graph can also be serialized by passing `node_link_data` as an encoder function. The two methods are equivalent.
86 >>> s1 = json.dumps(G, default=nx.node_link_data)
87 >>> s1
88 '{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, {"id": "B"}], "links": [{"source": "A", "target": "B"}]}'
90 The attribute names for storing NetworkX-internal graph data can
91 be specified as keyword options.
93 >>> H = nx.gn_graph(2)
94 >>> data2 = nx.node_link_data(H, link="edges", source="from", target="to")
95 >>> data2
96 {'directed': True, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 0}, {'id': 1}], 'edges': [{'from': 1, 'to': 0}]}
98 Notes
99 -----
100 Graph, node, and link attributes are stored in this format. Note that
101 attribute keys will be converted to strings in order to comply with JSON.
103 Attribute 'key' is only used for multigraphs.
105 To use `node_link_data` in conjunction with `node_link_graph`,
106 the keyword names for the attributes must match.
109 See Also
110 --------
111 node_link_graph, adjacency_data, tree_data
112 """
113 multigraph = G.is_multigraph()
115 # Allow 'key' to be omitted from attrs if the graph is not a multigraph.
116 key = None if not multigraph else key
117 if len({source, target, key}) < 3:
118 raise nx.NetworkXError("Attribute names are not unique.")
119 data = {
120 "directed": G.is_directed(),
121 "multigraph": multigraph,
122 "graph": G.graph,
123 "nodes": [{**G.nodes[n], name: n} for n in G],
124 }
125 if multigraph:
126 data[link] = [
127 {**d, source: u, target: v, key: k}
128 for u, v, k, d in G.edges(keys=True, data=True)
129 ]
130 else:
131 data[link] = [{**d, source: u, target: v} for u, v, d in G.edges(data=True)]
132 return data
135@nx._dispatch(graphs=None)
136def node_link_graph(
137 data,
138 directed=False,
139 multigraph=True,
140 *,
141 source="source",
142 target="target",
143 name="id",
144 key="key",
145 link="links",
146):
147 """Returns graph from node-link data format.
148 Useful for de-serialization from JSON.
150 Parameters
151 ----------
152 data : dict
153 node-link formatted graph data
155 directed : bool
156 If True, and direction not specified in data, return a directed graph.
158 multigraph : bool
159 If True, and multigraph not specified in data, return a multigraph.
161 source : string
162 A string that provides the 'source' attribute name for storing NetworkX-internal graph data.
163 target : string
164 A string that provides the 'target' attribute name for storing NetworkX-internal graph data.
165 name : string
166 A string that provides the 'name' attribute name for storing NetworkX-internal graph data.
167 key : string
168 A string that provides the 'key' attribute name for storing NetworkX-internal graph data.
169 link : string
170 A string that provides the 'link' attribute name for storing NetworkX-internal graph data.
172 Returns
173 -------
174 G : NetworkX graph
175 A NetworkX graph object
177 Examples
178 --------
180 Create data in node-link format by converting a graph.
182 >>> G = nx.Graph([('A', 'B')])
183 >>> data = nx.node_link_data(G)
184 >>> data
185 {'directed': False, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 'A'}, {'id': 'B'}], 'links': [{'source': 'A', 'target': 'B'}]}
187 Revert data in node-link format to a graph.
189 >>> H = nx.node_link_graph(data)
190 >>> print(H.edges)
191 [('A', 'B')]
193 To serialize and deserialize a graph with JSON,
195 >>> import json
196 >>> d = json.dumps(node_link_data(G))
197 >>> H = node_link_graph(json.loads(d))
198 >>> print(G.edges, H.edges)
199 [('A', 'B')] [('A', 'B')]
202 Notes
203 -----
204 Attribute 'key' is only used for multigraphs.
206 To use `node_link_data` in conjunction with `node_link_graph`,
207 the keyword names for the attributes must match.
209 See Also
210 --------
211 node_link_data, adjacency_data, tree_data
212 """
213 multigraph = data.get("multigraph", multigraph)
214 directed = data.get("directed", directed)
215 if multigraph:
216 graph = nx.MultiGraph()
217 else:
218 graph = nx.Graph()
219 if directed:
220 graph = graph.to_directed()
222 # Allow 'key' to be omitted from attrs if the graph is not a multigraph.
223 key = None if not multigraph else key
224 graph.graph = data.get("graph", {})
225 c = count()
226 for d in data["nodes"]:
227 node = _to_tuple(d.get(name, next(c)))
228 nodedata = {str(k): v for k, v in d.items() if k != name}
229 graph.add_node(node, **nodedata)
230 for d in data[link]:
231 src = tuple(d[source]) if isinstance(d[source], list) else d[source]
232 tgt = tuple(d[target]) if isinstance(d[target], list) else d[target]
233 if not multigraph:
234 edgedata = {str(k): v for k, v in d.items() if k != source and k != target}
235 graph.add_edge(src, tgt, **edgedata)
236 else:
237 ky = d.get(key, None)
238 edgedata = {
239 str(k): v
240 for k, v in d.items()
241 if k != source and k != target and k != key
242 }
243 graph.add_edge(src, tgt, ky, **edgedata)
244 return graph