Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
*********
|
||||
JSON data
|
||||
*********
|
||||
Generate and parse JSON serializable data for NetworkX graphs.
|
||||
|
||||
These formats are suitable for use with the d3.js examples https://d3js.org/
|
||||
|
||||
The three formats that you can generate with NetworkX are:
|
||||
|
||||
- node-link like in the d3.js example https://bl.ocks.org/mbostock/4062045
|
||||
- tree like in the d3.js example https://bl.ocks.org/mbostock/4063550
|
||||
- adjacency like in the d3.js example https://bost.ocks.org/mike/miserables/
|
||||
"""
|
||||
from networkx.readwrite.json_graph.node_link import *
|
||||
from networkx.readwrite.json_graph.adjacency import *
|
||||
from networkx.readwrite.json_graph.tree import *
|
||||
from networkx.readwrite.json_graph.jit import *
|
||||
from networkx.readwrite.json_graph.cytoscape import *
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,156 @@
|
|||
from itertools import chain
|
||||
import networkx as nx
|
||||
|
||||
__all__ = ["adjacency_data", "adjacency_graph"]
|
||||
|
||||
_attrs = dict(id="id", key="key")
|
||||
|
||||
|
||||
def adjacency_data(G, attrs=_attrs):
|
||||
"""Returns data in adjacency format that is suitable for JSON serialization
|
||||
and use in Javascript documents.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX graph
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains two keys 'id' and 'key'. The corresponding
|
||||
values provide the attribute names for storing NetworkX-internal graph
|
||||
data. The values should be unique. Default value:
|
||||
:samp:`dict(id='id', key='key')`.
|
||||
|
||||
If some user-defined graph data use these attribute names as data keys,
|
||||
they may be silently dropped.
|
||||
|
||||
Returns
|
||||
-------
|
||||
data : dict
|
||||
A dictionary with adjacency formatted data.
|
||||
|
||||
Raises
|
||||
------
|
||||
NetworkXError
|
||||
If values in attrs are not unique.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from networkx.readwrite import json_graph
|
||||
>>> G = nx.Graph([(1, 2)])
|
||||
>>> data = json_graph.adjacency_data(G)
|
||||
|
||||
To serialize with json
|
||||
|
||||
>>> import json
|
||||
>>> s = json.dumps(data)
|
||||
|
||||
Notes
|
||||
-----
|
||||
Graph, node, and link attributes will be written when using this format
|
||||
but attribute keys must be strings if you want to serialize the resulting
|
||||
data with JSON.
|
||||
|
||||
The default value of attrs will be changed in a future release of NetworkX.
|
||||
|
||||
See Also
|
||||
--------
|
||||
adjacency_graph, node_link_data, tree_data
|
||||
"""
|
||||
multigraph = G.is_multigraph()
|
||||
id_ = attrs["id"]
|
||||
# Allow 'key' to be omitted from attrs if the graph is not a multigraph.
|
||||
key = None if not multigraph else attrs["key"]
|
||||
if id_ == key:
|
||||
raise nx.NetworkXError("Attribute names are not unique.")
|
||||
data = {}
|
||||
data["directed"] = G.is_directed()
|
||||
data["multigraph"] = multigraph
|
||||
data["graph"] = list(G.graph.items())
|
||||
data["nodes"] = []
|
||||
data["adjacency"] = []
|
||||
for n, nbrdict in G.adjacency():
|
||||
data["nodes"].append(dict(chain(G.nodes[n].items(), [(id_, n)])))
|
||||
adj = []
|
||||
if multigraph:
|
||||
for nbr, keys in nbrdict.items():
|
||||
for k, d in keys.items():
|
||||
adj.append(dict(chain(d.items(), [(id_, nbr), (key, k)])))
|
||||
else:
|
||||
for nbr, d in nbrdict.items():
|
||||
adj.append(dict(chain(d.items(), [(id_, nbr)])))
|
||||
data["adjacency"].append(adj)
|
||||
return data
|
||||
|
||||
|
||||
def adjacency_graph(data, directed=False, multigraph=True, attrs=_attrs):
|
||||
"""Returns graph from adjacency data format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : dict
|
||||
Adjacency list formatted graph data
|
||||
|
||||
Returns
|
||||
-------
|
||||
G : NetworkX graph
|
||||
A NetworkX graph object
|
||||
|
||||
directed : bool
|
||||
If True, and direction not specified in data, return a directed graph.
|
||||
|
||||
multigraph : bool
|
||||
If True, and multigraph not specified in data, return a multigraph.
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains two keys 'id' and 'key'. The corresponding
|
||||
values provide the attribute names for storing NetworkX-internal graph
|
||||
data. The values should be unique. Default value:
|
||||
:samp:`dict(id='id', key='key')`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from networkx.readwrite import json_graph
|
||||
>>> G = nx.Graph([(1, 2)])
|
||||
>>> data = json_graph.adjacency_data(G)
|
||||
>>> H = json_graph.adjacency_graph(data)
|
||||
|
||||
Notes
|
||||
-----
|
||||
The default value of attrs will be changed in a future release of NetworkX.
|
||||
|
||||
See Also
|
||||
--------
|
||||
adjacency_graph, node_link_data, tree_data
|
||||
"""
|
||||
multigraph = data.get("multigraph", multigraph)
|
||||
directed = data.get("directed", directed)
|
||||
if multigraph:
|
||||
graph = nx.MultiGraph()
|
||||
else:
|
||||
graph = nx.Graph()
|
||||
if directed:
|
||||
graph = graph.to_directed()
|
||||
id_ = attrs["id"]
|
||||
# Allow 'key' to be omitted from attrs if the graph is not a multigraph.
|
||||
key = None if not multigraph else attrs["key"]
|
||||
graph.graph = dict(data.get("graph", []))
|
||||
mapping = []
|
||||
for d in data["nodes"]:
|
||||
node_data = d.copy()
|
||||
node = node_data.pop(id_)
|
||||
mapping.append(node)
|
||||
graph.add_node(node)
|
||||
graph.nodes[node].update(node_data)
|
||||
for i, d in enumerate(data["adjacency"]):
|
||||
source = mapping[i]
|
||||
for tdata in d:
|
||||
target_data = tdata.copy()
|
||||
target = target_data.pop(id_)
|
||||
if not multigraph:
|
||||
graph.add_edge(source, target)
|
||||
graph[source][target].update(tdata)
|
||||
else:
|
||||
ky = target_data.pop(key, None)
|
||||
graph.add_edge(source, target, key=ky)
|
||||
graph[source][target][ky].update(tdata)
|
||||
return graph
|
|
@ -0,0 +1,110 @@
|
|||
import networkx as nx
|
||||
|
||||
__all__ = ["cytoscape_data", "cytoscape_graph"]
|
||||
|
||||
_attrs = dict(name="name", ident="id")
|
||||
|
||||
|
||||
def cytoscape_data(G, attrs=None):
|
||||
"""Returns data in Cytoscape JSON format (cyjs).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX Graph
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
data: dict
|
||||
A dictionary with cyjs formatted data.
|
||||
Raises
|
||||
------
|
||||
NetworkXError
|
||||
If values in attrs are not unique.
|
||||
"""
|
||||
if not attrs:
|
||||
attrs = _attrs
|
||||
else:
|
||||
attrs.update({k: v for (k, v) in _attrs.items() if k not in attrs})
|
||||
|
||||
name = attrs["name"]
|
||||
ident = attrs["ident"]
|
||||
|
||||
if len({name, ident}) < 2:
|
||||
raise nx.NetworkXError("Attribute names are not unique.")
|
||||
|
||||
jsondata = {"data": list(G.graph.items())}
|
||||
jsondata["directed"] = G.is_directed()
|
||||
jsondata["multigraph"] = G.is_multigraph()
|
||||
jsondata["elements"] = {"nodes": [], "edges": []}
|
||||
nodes = jsondata["elements"]["nodes"]
|
||||
edges = jsondata["elements"]["edges"]
|
||||
|
||||
for i, j in G.nodes.items():
|
||||
n = {"data": j.copy()}
|
||||
n["data"]["id"] = j.get(ident) or str(i)
|
||||
n["data"]["value"] = i
|
||||
n["data"]["name"] = j.get(name) or str(i)
|
||||
nodes.append(n)
|
||||
|
||||
if G.is_multigraph():
|
||||
for e in G.edges(keys=True):
|
||||
n = {"data": G.adj[e[0]][e[1]][e[2]].copy()}
|
||||
n["data"]["source"] = e[0]
|
||||
n["data"]["target"] = e[1]
|
||||
n["data"]["key"] = e[2]
|
||||
edges.append(n)
|
||||
else:
|
||||
for e in G.edges():
|
||||
n = {"data": G.adj[e[0]][e[1]].copy()}
|
||||
n["data"]["source"] = e[0]
|
||||
n["data"]["target"] = e[1]
|
||||
edges.append(n)
|
||||
return jsondata
|
||||
|
||||
|
||||
def cytoscape_graph(data, attrs=None):
|
||||
if not attrs:
|
||||
attrs = _attrs
|
||||
else:
|
||||
attrs.update({k: v for (k, v) in _attrs.items() if k not in attrs})
|
||||
|
||||
name = attrs["name"]
|
||||
ident = attrs["ident"]
|
||||
|
||||
if len({ident, name}) < 2:
|
||||
raise nx.NetworkXError("Attribute names are not unique.")
|
||||
|
||||
multigraph = data.get("multigraph")
|
||||
directed = data.get("directed")
|
||||
if multigraph:
|
||||
graph = nx.MultiGraph()
|
||||
else:
|
||||
graph = nx.Graph()
|
||||
if directed:
|
||||
graph = graph.to_directed()
|
||||
graph.graph = dict(data.get("data"))
|
||||
for d in data["elements"]["nodes"]:
|
||||
node_data = d["data"].copy()
|
||||
node = d["data"]["value"]
|
||||
|
||||
if d["data"].get(name):
|
||||
node_data[name] = d["data"].get(name)
|
||||
if d["data"].get(ident):
|
||||
node_data[ident] = d["data"].get(ident)
|
||||
|
||||
graph.add_node(node)
|
||||
graph.nodes[node].update(node_data)
|
||||
|
||||
for d in data["elements"]["edges"]:
|
||||
edge_data = d["data"].copy()
|
||||
sour = d["data"].pop("source")
|
||||
targ = d["data"].pop("target")
|
||||
if multigraph:
|
||||
key = d["data"].get("key", 0)
|
||||
graph.add_edge(sour, targ, key=key)
|
||||
graph.edges[sour, targ, key].update(edge_data)
|
||||
else:
|
||||
graph.add_edge(sour, targ)
|
||||
graph.edges[sour, targ].update(edge_data)
|
||||
return graph
|
103
venv/Lib/site-packages/networkx/readwrite/json_graph/jit.py
Normal file
103
venv/Lib/site-packages/networkx/readwrite/json_graph/jit.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
"""
|
||||
Read and write NetworkX graphs as JavaScript InfoVis Toolkit (JIT) format JSON.
|
||||
|
||||
See the `JIT documentation`_ for more examples.
|
||||
|
||||
Format
|
||||
------
|
||||
var json = [
|
||||
{
|
||||
"id": "aUniqueIdentifier",
|
||||
"name": "usually a nodes name",
|
||||
"data": {
|
||||
"some key": "some value",
|
||||
"some other key": "some other value"
|
||||
},
|
||||
"adjacencies": [
|
||||
{
|
||||
nodeTo:"aNodeId",
|
||||
data: {} //put whatever you want here
|
||||
},
|
||||
'other adjacencies go here...'
|
||||
},
|
||||
|
||||
'other nodes go here...'
|
||||
];
|
||||
.. _JIT documentation: http://thejit.org
|
||||
"""
|
||||
|
||||
import json
|
||||
import networkx as nx
|
||||
from networkx.utils.decorators import not_implemented_for
|
||||
|
||||
__all__ = ["jit_graph", "jit_data"]
|
||||
|
||||
|
||||
def jit_graph(data, create_using=None):
|
||||
"""Read a graph from JIT JSON.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : JSON Graph Object
|
||||
|
||||
create_using : Networkx Graph, optional (default: Graph())
|
||||
Return graph of this type. The provided instance will be cleared.
|
||||
|
||||
Returns
|
||||
-------
|
||||
G : NetworkX Graph built from create_using if provided.
|
||||
"""
|
||||
if create_using is None:
|
||||
G = nx.Graph()
|
||||
else:
|
||||
G = create_using
|
||||
G.clear()
|
||||
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
|
||||
for node in data:
|
||||
G.add_node(node["id"], **node["data"])
|
||||
if node.get("adjacencies") is not None:
|
||||
for adj in node["adjacencies"]:
|
||||
G.add_edge(node["id"], adj["nodeTo"], **adj["data"])
|
||||
return G
|
||||
|
||||
|
||||
@not_implemented_for("multigraph")
|
||||
def jit_data(G, indent=None, default=None):
|
||||
"""Returns data in JIT JSON format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX Graph
|
||||
|
||||
indent: optional, default=None
|
||||
If indent is a non-negative integer, then JSON array elements and
|
||||
object members will be pretty-printed with that indent level.
|
||||
An indent level of 0, or negative, will only insert newlines.
|
||||
None (the default) selects the most compact representation.
|
||||
|
||||
default: optional, default=None
|
||||
It will pass the value to the json.dumps function in order to
|
||||
be able to serialize custom objects used as nodes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
data: JIT JSON string
|
||||
"""
|
||||
json_graph = []
|
||||
for node in G.nodes():
|
||||
json_node = {"id": node, "name": node}
|
||||
# node data
|
||||
json_node["data"] = G.nodes[node]
|
||||
# adjacencies
|
||||
if G[node]:
|
||||
json_node["adjacencies"] = []
|
||||
for neighbour in G[node]:
|
||||
adjacency = {"nodeTo": neighbour}
|
||||
# adjacency data
|
||||
adjacency["data"] = G.edges[node, neighbour]
|
||||
json_node["adjacencies"].append(adjacency)
|
||||
json_graph.append(json_node)
|
||||
return json.dumps(json_graph, indent=indent, default=default)
|
|
@ -0,0 +1,184 @@
|
|||
from itertools import chain, count
|
||||
import networkx as nx
|
||||
from networkx.utils import to_tuple
|
||||
|
||||
__all__ = ["node_link_data", "node_link_graph"]
|
||||
|
||||
|
||||
_attrs = dict(source="source", target="target", name="id", key="key", link="links")
|
||||
|
||||
|
||||
def node_link_data(G, attrs=None):
|
||||
"""Returns data in node-link format that is suitable for JSON serialization
|
||||
and use in Javascript documents.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
G : NetworkX graph
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains five keys 'source', 'target', 'name',
|
||||
'key' and 'link'. The corresponding values provide the attribute
|
||||
names for storing NetworkX-internal graph data. The values should
|
||||
be unique. Default value::
|
||||
|
||||
dict(source='source', target='target', name='id',
|
||||
key='key', link='links')
|
||||
|
||||
If some user-defined graph data use these attribute names as data keys,
|
||||
they may be silently dropped.
|
||||
|
||||
Returns
|
||||
-------
|
||||
data : dict
|
||||
A dictionary with node-link formatted data.
|
||||
|
||||
Raises
|
||||
------
|
||||
NetworkXError
|
||||
If values in attrs are not unique.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from networkx.readwrite import json_graph
|
||||
>>> G = nx.Graph([("A", "B")])
|
||||
>>> data1 = json_graph.node_link_data(G)
|
||||
>>> H = nx.gn_graph(2)
|
||||
>>> data2 = json_graph.node_link_data(
|
||||
... H, {"link": "edges", "source": "from", "target": "to"}
|
||||
... )
|
||||
|
||||
To serialize with json
|
||||
|
||||
>>> import json
|
||||
>>> s1 = json.dumps(data1)
|
||||
>>> s2 = json.dumps(
|
||||
... data2, default={"link": "edges", "source": "from", "target": "to"}
|
||||
... )
|
||||
|
||||
Notes
|
||||
-----
|
||||
Graph, node, and link attributes are stored in this format. Note that
|
||||
attribute keys will be converted to strings in order to comply with JSON.
|
||||
|
||||
Attribute 'key' is only used for multigraphs.
|
||||
|
||||
See Also
|
||||
--------
|
||||
node_link_graph, adjacency_data, tree_data
|
||||
"""
|
||||
multigraph = G.is_multigraph()
|
||||
# Allow 'attrs' to keep default values.
|
||||
if attrs is None:
|
||||
attrs = _attrs
|
||||
else:
|
||||
attrs.update({k: v for (k, v) in _attrs.items() if k not in attrs})
|
||||
name = attrs["name"]
|
||||
source = attrs["source"]
|
||||
target = attrs["target"]
|
||||
links = attrs["link"]
|
||||
# Allow 'key' to be omitted from attrs if the graph is not a multigraph.
|
||||
key = None if not multigraph else attrs["key"]
|
||||
if len({source, target, key}) < 3:
|
||||
raise nx.NetworkXError("Attribute names are not unique.")
|
||||
data = {
|
||||
"directed": G.is_directed(),
|
||||
"multigraph": multigraph,
|
||||
"graph": G.graph,
|
||||
"nodes": [dict(chain(G.nodes[n].items(), [(name, n)])) for n in G],
|
||||
}
|
||||
if multigraph:
|
||||
data[links] = [
|
||||
dict(chain(d.items(), [(source, u), (target, v), (key, k)]))
|
||||
for u, v, k, d in G.edges(keys=True, data=True)
|
||||
]
|
||||
else:
|
||||
data[links] = [
|
||||
dict(chain(d.items(), [(source, u), (target, v)]))
|
||||
for u, v, d in G.edges(data=True)
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
def node_link_graph(data, directed=False, multigraph=True, attrs=None):
|
||||
"""Returns graph from node-link data format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : dict
|
||||
node-link formatted graph data
|
||||
|
||||
directed : bool
|
||||
If True, and direction not specified in data, return a directed graph.
|
||||
|
||||
multigraph : bool
|
||||
If True, and multigraph not specified in data, return a multigraph.
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains five keys 'source', 'target', 'name',
|
||||
'key' and 'link'. The corresponding values provide the attribute
|
||||
names for storing NetworkX-internal graph data. Default value:
|
||||
|
||||
dict(source='source', target='target', name='id',
|
||||
key='key', link='links')
|
||||
|
||||
Returns
|
||||
-------
|
||||
G : NetworkX graph
|
||||
A NetworkX graph object
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from networkx.readwrite import json_graph
|
||||
>>> G = nx.Graph([("A", "B")])
|
||||
>>> data = json_graph.node_link_data(G)
|
||||
>>> H = json_graph.node_link_graph(data)
|
||||
|
||||
Notes
|
||||
-----
|
||||
Attribute 'key' is only used for multigraphs.
|
||||
|
||||
See Also
|
||||
--------
|
||||
node_link_data, adjacency_data, tree_data
|
||||
"""
|
||||
# Allow 'attrs' to keep default values.
|
||||
if attrs is None:
|
||||
attrs = _attrs
|
||||
else:
|
||||
attrs.update({k: v for k, v in _attrs.items() if k not in attrs})
|
||||
multigraph = data.get("multigraph", multigraph)
|
||||
directed = data.get("directed", directed)
|
||||
if multigraph:
|
||||
graph = nx.MultiGraph()
|
||||
else:
|
||||
graph = nx.Graph()
|
||||
if directed:
|
||||
graph = graph.to_directed()
|
||||
name = attrs["name"]
|
||||
source = attrs["source"]
|
||||
target = attrs["target"]
|
||||
links = attrs["link"]
|
||||
# Allow 'key' to be omitted from attrs if the graph is not a multigraph.
|
||||
key = None if not multigraph else attrs["key"]
|
||||
graph.graph = data.get("graph", {})
|
||||
c = count()
|
||||
for d in data["nodes"]:
|
||||
node = to_tuple(d.get(name, next(c)))
|
||||
nodedata = {str(k): v for k, v in d.items() if k != name}
|
||||
graph.add_node(node, **nodedata)
|
||||
for d in data[links]:
|
||||
src = tuple(d[source]) if isinstance(d[source], list) else d[source]
|
||||
tgt = tuple(d[target]) if isinstance(d[target], list) else d[target]
|
||||
if not multigraph:
|
||||
edgedata = {str(k): v for k, v in d.items() if k != source and k != target}
|
||||
graph.add_edge(src, tgt, **edgedata)
|
||||
else:
|
||||
ky = d.get(key, None)
|
||||
edgedata = {
|
||||
str(k): v
|
||||
for k, v in d.items()
|
||||
if k != source and k != target and k != key
|
||||
}
|
||||
graph.add_edge(src, tgt, ky, **edgedata)
|
||||
return graph
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,58 @@
|
|||
import json
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.readwrite.json_graph import adjacency_data, adjacency_graph
|
||||
|
||||
|
||||
class TestAdjacency:
|
||||
def test_graph(self):
|
||||
G = nx.path_graph(4)
|
||||
H = adjacency_graph(adjacency_data(G))
|
||||
nx.is_isomorphic(G, H)
|
||||
|
||||
def test_graph_attributes(self):
|
||||
G = nx.path_graph(4)
|
||||
G.add_node(1, color="red")
|
||||
G.add_edge(1, 2, width=7)
|
||||
G.graph["foo"] = "bar"
|
||||
G.graph[1] = "one"
|
||||
|
||||
H = adjacency_graph(adjacency_data(G))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
|
||||
d = json.dumps(adjacency_data(G))
|
||||
H = adjacency_graph(json.loads(d))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.graph[1] == "one"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, [1, 2, 3])
|
||||
H = adjacency_graph(adjacency_data(G))
|
||||
assert H.is_directed()
|
||||
nx.is_isomorphic(G, H)
|
||||
|
||||
def test_multidigraph(self):
|
||||
G = nx.MultiDiGraph()
|
||||
nx.add_path(G, [1, 2, 3])
|
||||
H = adjacency_graph(adjacency_data(G))
|
||||
assert H.is_directed()
|
||||
assert H.is_multigraph()
|
||||
|
||||
def test_multigraph(self):
|
||||
G = nx.MultiGraph()
|
||||
G.add_edge(1, 2, key="first")
|
||||
G.add_edge(1, 2, key="second", color="blue")
|
||||
H = adjacency_graph(adjacency_data(G))
|
||||
nx.is_isomorphic(G, H)
|
||||
assert H[1][2]["second"]["color"] == "blue"
|
||||
|
||||
def test_exception(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.MultiDiGraph()
|
||||
attrs = dict(id="node", key="node")
|
||||
adjacency_data(G, attrs)
|
|
@ -0,0 +1,63 @@
|
|||
import json
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.readwrite.json_graph import cytoscape_data, cytoscape_graph
|
||||
|
||||
|
||||
class TestCytoscape:
|
||||
def test_graph(self):
|
||||
G = nx.path_graph(4)
|
||||
H = cytoscape_graph(cytoscape_data(G))
|
||||
nx.is_isomorphic(G, H)
|
||||
|
||||
def test_graph_attributes(self):
|
||||
G = nx.path_graph(4)
|
||||
G.add_node(1, color="red")
|
||||
G.add_edge(1, 2, width=7)
|
||||
G.graph["foo"] = "bar"
|
||||
G.graph[1] = "one"
|
||||
G.add_node(3, name="node", id="123")
|
||||
|
||||
H = cytoscape_graph(cytoscape_data(G))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
assert H.nodes[3]["name"] == "node"
|
||||
assert H.nodes[3]["id"] == "123"
|
||||
|
||||
d = json.dumps(cytoscape_data(G))
|
||||
H = cytoscape_graph(json.loads(d))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.graph[1] == "one"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
assert H.nodes[3]["name"] == "node"
|
||||
assert H.nodes[3]["id"] == "123"
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, [1, 2, 3])
|
||||
H = cytoscape_graph(cytoscape_data(G))
|
||||
assert H.is_directed()
|
||||
nx.is_isomorphic(G, H)
|
||||
|
||||
def test_multidigraph(self):
|
||||
G = nx.MultiDiGraph()
|
||||
nx.add_path(G, [1, 2, 3])
|
||||
H = cytoscape_graph(cytoscape_data(G))
|
||||
assert H.is_directed()
|
||||
assert H.is_multigraph()
|
||||
|
||||
def test_multigraph(self):
|
||||
G = nx.MultiGraph()
|
||||
G.add_edge(1, 2, key="first")
|
||||
G.add_edge(1, 2, key="second", color="blue")
|
||||
H = cytoscape_graph(cytoscape_data(G))
|
||||
assert nx.is_isomorphic(G, H)
|
||||
assert H[1][2]["second"]["color"] == "blue"
|
||||
|
||||
def test_exception(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.MultiDiGraph()
|
||||
attrs = dict(name="node", ident="node")
|
||||
cytoscape_data(G, attrs)
|
|
@ -0,0 +1,64 @@
|
|||
import json
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.readwrite.json_graph import jit_data, jit_graph
|
||||
|
||||
|
||||
class TestJIT:
|
||||
def test_jit(self):
|
||||
G = nx.Graph()
|
||||
G.add_node("Node1", node_data="foobar")
|
||||
G.add_node("Node3", node_data="bar")
|
||||
G.add_node("Node4")
|
||||
G.add_edge("Node1", "Node2", weight=9, something="isSomething")
|
||||
G.add_edge("Node2", "Node3", weight=4, something="isNotSomething")
|
||||
G.add_edge("Node1", "Node2")
|
||||
d = jit_data(G)
|
||||
K = jit_graph(json.loads(d))
|
||||
assert nx.is_isomorphic(G, K)
|
||||
|
||||
def test_jit_2(self):
|
||||
G = nx.Graph()
|
||||
G.add_node(1, node_data=3)
|
||||
G.add_node(3, node_data=0)
|
||||
G.add_edge(1, 2, weight=9, something=0)
|
||||
G.add_edge(2, 3, weight=4, something=3)
|
||||
G.add_edge(1, 2)
|
||||
d = jit_data(G)
|
||||
K = jit_graph(json.loads(d))
|
||||
assert nx.is_isomorphic(G, K)
|
||||
|
||||
def test_jit_directed(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_node(1, node_data=3)
|
||||
G.add_node(3, node_data=0)
|
||||
G.add_edge(1, 2, weight=9, something=0)
|
||||
G.add_edge(2, 3, weight=4, something=3)
|
||||
G.add_edge(1, 2)
|
||||
d = jit_data(G)
|
||||
K = jit_graph(json.loads(d), create_using=nx.DiGraph())
|
||||
assert nx.is_isomorphic(G, K)
|
||||
|
||||
def test_jit_multi_directed(self):
|
||||
G = nx.MultiDiGraph()
|
||||
G.add_node(1, node_data=3)
|
||||
G.add_node(3, node_data=0)
|
||||
G.add_edge(1, 2, weight=9, something=0)
|
||||
G.add_edge(2, 3, weight=4, something=3)
|
||||
G.add_edge(1, 2)
|
||||
pytest.raises(nx.NetworkXNotImplemented, jit_data, G)
|
||||
|
||||
H = nx.DiGraph(G)
|
||||
d = jit_data(H)
|
||||
K = jit_graph(json.loads(d), create_using=nx.MultiDiGraph())
|
||||
assert nx.is_isomorphic(H, K)
|
||||
K.add_edge(1, 2)
|
||||
assert not nx.is_isomorphic(H, K)
|
||||
assert nx.is_isomorphic(G, K)
|
||||
|
||||
def test_jit_round_trip(self):
|
||||
G = nx.Graph()
|
||||
d = nx.jit_data(G)
|
||||
H = jit_graph(json.loads(d))
|
||||
K = jit_graph(d)
|
||||
assert nx.is_isomorphic(H, K)
|
|
@ -0,0 +1,104 @@
|
|||
import json
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.readwrite.json_graph import node_link_data, node_link_graph
|
||||
|
||||
|
||||
class TestNodeLink:
|
||||
def test_graph(self):
|
||||
G = nx.path_graph(4)
|
||||
H = node_link_graph(node_link_data(G))
|
||||
assert nx.is_isomorphic(G, H)
|
||||
|
||||
def test_graph_attributes(self):
|
||||
G = nx.path_graph(4)
|
||||
G.add_node(1, color="red")
|
||||
G.add_edge(1, 2, width=7)
|
||||
G.graph[1] = "one"
|
||||
G.graph["foo"] = "bar"
|
||||
|
||||
H = node_link_graph(node_link_data(G))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
|
||||
d = json.dumps(node_link_data(G))
|
||||
H = node_link_graph(json.loads(d))
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.graph["1"] == "one"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.DiGraph()
|
||||
H = node_link_graph(node_link_data(G))
|
||||
assert H.is_directed()
|
||||
|
||||
def test_multigraph(self):
|
||||
G = nx.MultiGraph()
|
||||
G.add_edge(1, 2, key="first")
|
||||
G.add_edge(1, 2, key="second", color="blue")
|
||||
H = node_link_graph(node_link_data(G))
|
||||
nx.is_isomorphic(G, H)
|
||||
assert H[1][2]["second"]["color"] == "blue"
|
||||
|
||||
def test_graph_with_tuple_nodes(self):
|
||||
G = nx.Graph()
|
||||
G.add_edge((0, 0), (1, 0), color=[255, 255, 0])
|
||||
d = node_link_data(G)
|
||||
dumped_d = json.dumps(d)
|
||||
dd = json.loads(dumped_d)
|
||||
H = node_link_graph(dd)
|
||||
assert H.nodes[(0, 0)] == G.nodes[(0, 0)]
|
||||
assert H[(0, 0)][(1, 0)]["color"] == [255, 255, 0]
|
||||
|
||||
def test_unicode_keys(self):
|
||||
q = "qualité"
|
||||
G = nx.Graph()
|
||||
G.add_node(1, **{q: q})
|
||||
s = node_link_data(G)
|
||||
output = json.dumps(s, ensure_ascii=False)
|
||||
data = json.loads(output)
|
||||
H = node_link_graph(data)
|
||||
assert H.nodes[1][q] == q
|
||||
|
||||
def test_exception(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.MultiDiGraph()
|
||||
attrs = dict(name="node", source="node", target="node", key="node")
|
||||
node_link_data(G, attrs)
|
||||
|
||||
def test_string_ids(self):
|
||||
q = "qualité"
|
||||
G = nx.DiGraph()
|
||||
G.add_node("A")
|
||||
G.add_node(q)
|
||||
G.add_edge("A", q)
|
||||
data = node_link_data(G)
|
||||
assert data["links"][0]["source"] == "A"
|
||||
assert data["links"][0]["target"] == q
|
||||
H = node_link_graph(data)
|
||||
assert nx.is_isomorphic(G, H)
|
||||
|
||||
def test_custom_attrs(self):
|
||||
G = nx.path_graph(4)
|
||||
G.add_node(1, color="red")
|
||||
G.add_edge(1, 2, width=7)
|
||||
G.graph[1] = "one"
|
||||
G.graph["foo"] = "bar"
|
||||
|
||||
attrs = dict(
|
||||
source="c_source",
|
||||
target="c_target",
|
||||
name="c_id",
|
||||
key="c_key",
|
||||
link="c_links",
|
||||
)
|
||||
|
||||
H = node_link_graph(
|
||||
node_link_data(G, attrs=attrs), multigraph=False, attrs=attrs
|
||||
)
|
||||
assert nx.is_isomorphic(G, H)
|
||||
assert H.graph["foo"] == "bar"
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
assert H[1][2]["width"] == 7
|
|
@ -0,0 +1,35 @@
|
|||
import json
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.readwrite.json_graph import tree_data, tree_graph
|
||||
|
||||
|
||||
class TestTree:
|
||||
def test_graph(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_nodes_from([1, 2, 3], color="red")
|
||||
G.add_edge(1, 2, foo=7)
|
||||
G.add_edge(1, 3, foo=10)
|
||||
G.add_edge(3, 4, foo=10)
|
||||
H = tree_graph(tree_data(G, 1))
|
||||
nx.is_isomorphic(G, H)
|
||||
|
||||
def test_graph_attributes(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_nodes_from([1, 2, 3], color="red")
|
||||
G.add_edge(1, 2, foo=7)
|
||||
G.add_edge(1, 3, foo=10)
|
||||
G.add_edge(3, 4, foo=10)
|
||||
H = tree_graph(tree_data(G, 1))
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
|
||||
d = json.dumps(tree_data(G, 1))
|
||||
H = tree_graph(json.loads(d))
|
||||
assert H.nodes[1]["color"] == "red"
|
||||
|
||||
def test_exception(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.MultiDiGraph()
|
||||
G.add_node(0)
|
||||
attrs = dict(id="node", children="node")
|
||||
tree_data(G, 0, attrs)
|
146
venv/Lib/site-packages/networkx/readwrite/json_graph/tree.py
Normal file
146
venv/Lib/site-packages/networkx/readwrite/json_graph/tree.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
from itertools import chain
|
||||
import networkx as nx
|
||||
|
||||
__all__ = ["tree_data", "tree_graph"]
|
||||
|
||||
_attrs = dict(id="id", children="children")
|
||||
|
||||
|
||||
def tree_data(G, root, attrs=_attrs):
|
||||
"""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
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains two keys 'id' and 'children'. The
|
||||
corresponding values provide the attribute names for storing
|
||||
NetworkX-internal graph data. The values should be unique. Default
|
||||
value: :samp:`dict(id='id', children='children')`.
|
||||
|
||||
If some user-defined graph data use these attribute names as data keys,
|
||||
they may be silently dropped.
|
||||
|
||||
Returns
|
||||
-------
|
||||
data : dict
|
||||
A dictionary with node-link formatted data.
|
||||
|
||||
Raises
|
||||
------
|
||||
NetworkXError
|
||||
If values in attrs are not unique.
|
||||
|
||||
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.
|
||||
|
||||
The default value of attrs will be changed in a future release of NetworkX.
|
||||
|
||||
See Also
|
||||
--------
|
||||
tree_graph, node_link_data, node_link_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.")
|
||||
|
||||
id_ = attrs["id"]
|
||||
children = attrs["children"]
|
||||
if id_ == children:
|
||||
raise nx.NetworkXError("Attribute names are not unique.")
|
||||
|
||||
def add_children(n, G):
|
||||
nbrs = G[n]
|
||||
if len(nbrs) == 0:
|
||||
return []
|
||||
children_ = []
|
||||
for child in nbrs:
|
||||
d = dict(chain(G.nodes[child].items(), [(id_, child)]))
|
||||
c = add_children(child, G)
|
||||
if c:
|
||||
d[children] = c
|
||||
children_.append(d)
|
||||
return children_
|
||||
|
||||
data = dict(chain(G.nodes[root].items(), [(id_, root)]))
|
||||
data[children] = add_children(root, G)
|
||||
return data
|
||||
|
||||
|
||||
def tree_graph(data, attrs=_attrs):
|
||||
"""Returns graph from tree data format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data : dict
|
||||
Tree formatted graph data
|
||||
|
||||
Returns
|
||||
-------
|
||||
G : NetworkX DiGraph
|
||||
|
||||
attrs : dict
|
||||
A dictionary that contains two keys 'id' and 'children'. The
|
||||
corresponding values provide the attribute names for storing
|
||||
NetworkX-internal graph data. The values should be unique. Default
|
||||
value: :samp:`dict(id='id', children='children')`.
|
||||
|
||||
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)
|
||||
|
||||
Notes
|
||||
-----
|
||||
The default value of attrs will be changed in a future release of NetworkX.
|
||||
|
||||
See Also
|
||||
--------
|
||||
tree_graph, node_link_data, adjacency_data
|
||||
"""
|
||||
graph = nx.DiGraph()
|
||||
id_ = attrs["id"]
|
||||
children = attrs["children"]
|
||||
|
||||
def add_children(parent, children_):
|
||||
for data in children_:
|
||||
child = data[id_]
|
||||
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 != id_ and k != children
|
||||
}
|
||||
graph.add_node(child, **nodedata)
|
||||
|
||||
root = data[id_]
|
||||
children_ = data.get(children, [])
|
||||
nodedata = {str(k): v for k, v in data.items() if k != id_ and k != children}
|
||||
graph.add_node(root, **nodedata)
|
||||
add_children(root, children_)
|
||||
return graph
|
Loading…
Add table
Add a link
Reference in a new issue