190 lines
5.7 KiB
Python
190 lines
5.7 KiB
Python
import networkx as nx
|
|
|
|
__all__ = ["cytoscape_data", "cytoscape_graph"]
|
|
|
|
|
|
def cytoscape_data(G, name="name", ident="id"):
|
|
"""Returns data in Cytoscape JSON format (cyjs).
|
|
|
|
Parameters
|
|
----------
|
|
G : NetworkX Graph
|
|
The graph to convert to cytoscape format
|
|
name : string
|
|
A string which is mapped to the 'name' node element in cyjs format.
|
|
Must not have the same value as `ident`.
|
|
ident : string
|
|
A string which is mapped to the 'id' node element in cyjs format.
|
|
Must not have the same value as `name`.
|
|
|
|
Returns
|
|
-------
|
|
data: dict
|
|
A dictionary with cyjs formatted data.
|
|
|
|
Raises
|
|
------
|
|
NetworkXError
|
|
If the values for `name` and `ident` are identical.
|
|
|
|
See Also
|
|
--------
|
|
cytoscape_graph: convert a dictionary in cyjs format to a graph
|
|
|
|
References
|
|
----------
|
|
.. [1] Cytoscape user's manual:
|
|
http://manual.cytoscape.org/en/stable/index.html
|
|
|
|
Examples
|
|
--------
|
|
>>> from pprint import pprint
|
|
>>> G = nx.path_graph(2)
|
|
>>> cyto_data = nx.cytoscape_data(G)
|
|
>>> pprint(cyto_data, sort_dicts=False)
|
|
{'data': [],
|
|
'directed': False,
|
|
'multigraph': False,
|
|
'elements': {'nodes': [{'data': {'id': '0', 'value': 0, 'name': '0'}},
|
|
{'data': {'id': '1', 'value': 1, 'name': '1'}}],
|
|
'edges': [{'data': {'source': 0, 'target': 1}}]}}
|
|
|
|
The :mod:`json` package can be used to serialize the resulting data
|
|
|
|
>>> import io, json
|
|
>>> with io.StringIO() as fh: # replace io with `open(...)` to write to disk
|
|
... json.dump(cyto_data, fh)
|
|
... fh.seek(0) # doctest: +SKIP
|
|
... print(fh.getvalue()[:64]) # View the first 64 characters
|
|
{"data": [], "directed": false, "multigraph": false, "elements":
|
|
|
|
"""
|
|
if name == ident:
|
|
raise nx.NetworkXError("name and ident must be different.")
|
|
|
|
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
|
|
|
|
|
|
@nx._dispatchable(graphs=None, returns_graph=True)
|
|
def cytoscape_graph(data, name="name", ident="id"):
|
|
"""
|
|
Create a NetworkX graph from a dictionary in cytoscape JSON format.
|
|
|
|
Parameters
|
|
----------
|
|
data : dict
|
|
A dictionary of data conforming to cytoscape JSON format.
|
|
name : string
|
|
A string which is mapped to the 'name' node element in cyjs format.
|
|
Must not have the same value as `ident`.
|
|
ident : string
|
|
A string which is mapped to the 'id' node element in cyjs format.
|
|
Must not have the same value as `name`.
|
|
|
|
Returns
|
|
-------
|
|
graph : a NetworkX graph instance
|
|
The `graph` can be an instance of `Graph`, `DiGraph`, `MultiGraph`, or
|
|
`MultiDiGraph` depending on the input data.
|
|
|
|
Raises
|
|
------
|
|
NetworkXError
|
|
If the `name` and `ident` attributes are identical.
|
|
|
|
See Also
|
|
--------
|
|
cytoscape_data: convert a NetworkX graph to a dict in cyjs format
|
|
|
|
References
|
|
----------
|
|
.. [1] Cytoscape user's manual:
|
|
http://manual.cytoscape.org/en/stable/index.html
|
|
|
|
Examples
|
|
--------
|
|
>>> data_dict = {
|
|
... "data": [],
|
|
... "directed": False,
|
|
... "multigraph": False,
|
|
... "elements": {
|
|
... "nodes": [
|
|
... {"data": {"id": "0", "value": 0, "name": "0"}},
|
|
... {"data": {"id": "1", "value": 1, "name": "1"}},
|
|
... ],
|
|
... "edges": [{"data": {"source": 0, "target": 1}}],
|
|
... },
|
|
... }
|
|
>>> G = nx.cytoscape_graph(data_dict)
|
|
>>> G.name
|
|
''
|
|
>>> G.nodes()
|
|
NodeView((0, 1))
|
|
>>> G.nodes(data=True)[0]
|
|
{'id': '0', 'value': 0, 'name': '0'}
|
|
>>> G.edges(data=True)
|
|
EdgeDataView([(0, 1, {'source': 0, 'target': 1})])
|
|
"""
|
|
if name == ident:
|
|
raise nx.NetworkXError("name and ident must be different.")
|
|
|
|
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"]["source"]
|
|
targ = d["data"]["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
|