cytoscape.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import networkx as nx
  2. __all__ = ["cytoscape_data", "cytoscape_graph"]
  3. def cytoscape_data(G, name="name", ident="id"):
  4. """Returns data in Cytoscape JSON format (cyjs).
  5. Parameters
  6. ----------
  7. G : NetworkX Graph
  8. The graph to convert to cytoscape format
  9. name : string
  10. A string which is mapped to the 'name' node element in cyjs format.
  11. Must not have the same value as `ident`.
  12. ident : string
  13. A string which is mapped to the 'id' node element in cyjs format.
  14. Must not have the same value as `name`.
  15. Returns
  16. -------
  17. data: dict
  18. A dictionary with cyjs formatted data.
  19. Raises
  20. ------
  21. NetworkXError
  22. If the values for `name` and `ident` are identical.
  23. See Also
  24. --------
  25. cytoscape_graph: convert a dictionary in cyjs format to a graph
  26. References
  27. ----------
  28. .. [1] Cytoscape user's manual:
  29. http://manual.cytoscape.org/en/stable/index.html
  30. Examples
  31. --------
  32. >>> G = nx.path_graph(2)
  33. >>> nx.cytoscape_data(G) # doctest: +SKIP
  34. {'data': [],
  35. 'directed': False,
  36. 'multigraph': False,
  37. 'elements': {'nodes': [{'data': {'id': '0', 'value': 0, 'name': '0'}},
  38. {'data': {'id': '1', 'value': 1, 'name': '1'}}],
  39. 'edges': [{'data': {'source': 0, 'target': 1}}]}}
  40. """
  41. if name == ident:
  42. raise nx.NetworkXError("name and ident must be different.")
  43. jsondata = {"data": list(G.graph.items())}
  44. jsondata["directed"] = G.is_directed()
  45. jsondata["multigraph"] = G.is_multigraph()
  46. jsondata["elements"] = {"nodes": [], "edges": []}
  47. nodes = jsondata["elements"]["nodes"]
  48. edges = jsondata["elements"]["edges"]
  49. for i, j in G.nodes.items():
  50. n = {"data": j.copy()}
  51. n["data"]["id"] = j.get(ident) or str(i)
  52. n["data"]["value"] = i
  53. n["data"]["name"] = j.get(name) or str(i)
  54. nodes.append(n)
  55. if G.is_multigraph():
  56. for e in G.edges(keys=True):
  57. n = {"data": G.adj[e[0]][e[1]][e[2]].copy()}
  58. n["data"]["source"] = e[0]
  59. n["data"]["target"] = e[1]
  60. n["data"]["key"] = e[2]
  61. edges.append(n)
  62. else:
  63. for e in G.edges():
  64. n = {"data": G.adj[e[0]][e[1]].copy()}
  65. n["data"]["source"] = e[0]
  66. n["data"]["target"] = e[1]
  67. edges.append(n)
  68. return jsondata
  69. def cytoscape_graph(data, name="name", ident="id"):
  70. """
  71. Create a NetworkX graph from a dictionary in cytoscape JSON format.
  72. Parameters
  73. ----------
  74. data : dict
  75. A dictionary of data conforming to cytoscape JSON format.
  76. name : string
  77. A string which is mapped to the 'name' node element in cyjs format.
  78. Must not have the same value as `ident`.
  79. ident : string
  80. A string which is mapped to the 'id' node element in cyjs format.
  81. Must not have the same value as `name`.
  82. Returns
  83. -------
  84. graph : a NetworkX graph instance
  85. The `graph` can be an instance of `Graph`, `DiGraph`, `MultiGraph`, or
  86. `MultiDiGraph` depending on the input data.
  87. Raises
  88. ------
  89. NetworkXError
  90. If the `name` and `ident` attributes are identical.
  91. See Also
  92. --------
  93. cytoscape_data: convert a NetworkX graph to a dict in cyjs format
  94. References
  95. ----------
  96. .. [1] Cytoscape user's manual:
  97. http://manual.cytoscape.org/en/stable/index.html
  98. Examples
  99. --------
  100. >>> data_dict = {
  101. ... 'data': [],
  102. ... 'directed': False,
  103. ... 'multigraph': False,
  104. ... 'elements': {'nodes': [{'data': {'id': '0', 'value': 0, 'name': '0'}},
  105. ... {'data': {'id': '1', 'value': 1, 'name': '1'}}],
  106. ... 'edges': [{'data': {'source': 0, 'target': 1}}]}
  107. ... }
  108. >>> G = nx.cytoscape_graph(data_dict)
  109. >>> G.name
  110. ''
  111. >>> G.nodes()
  112. NodeView((0, 1))
  113. >>> G.nodes(data=True)[0]
  114. {'id': '0', 'value': 0, 'name': '0'}
  115. >>> G.edges(data=True)
  116. EdgeDataView([(0, 1, {'source': 0, 'target': 1})])
  117. """
  118. if name == ident:
  119. raise nx.NetworkXError("name and ident must be different.")
  120. multigraph = data.get("multigraph")
  121. directed = data.get("directed")
  122. if multigraph:
  123. graph = nx.MultiGraph()
  124. else:
  125. graph = nx.Graph()
  126. if directed:
  127. graph = graph.to_directed()
  128. graph.graph = dict(data.get("data"))
  129. for d in data["elements"]["nodes"]:
  130. node_data = d["data"].copy()
  131. node = d["data"]["value"]
  132. if d["data"].get(name):
  133. node_data[name] = d["data"].get(name)
  134. if d["data"].get(ident):
  135. node_data[ident] = d["data"].get(ident)
  136. graph.add_node(node)
  137. graph.nodes[node].update(node_data)
  138. for d in data["elements"]["edges"]:
  139. edge_data = d["data"].copy()
  140. sour = d["data"]["source"]
  141. targ = d["data"]["target"]
  142. if multigraph:
  143. key = d["data"].get("key", 0)
  144. graph.add_edge(sour, targ, key=key)
  145. graph.edges[sour, targ, key].update(edge_data)
  146. else:
  147. graph.add_edge(sour, targ)
  148. graph.edges[sour, targ].update(edge_data)
  149. return graph