import networkx as nx
__all__ = ["cytoscape_data", "cytoscape_graph"]
_attrs = dict(name="name", ident="id")
[docs]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
[docs]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