plot_snap.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. """
  2. ==================
  3. SNAP Graph Summary
  4. ==================
  5. An example of summarizing a graph based on node attributes and edge attributes
  6. using the Summarization by Grouping Nodes on Attributes and Pairwise
  7. edges (SNAP) algorithm (not to be confused with the Stanford Network
  8. Analysis Project). The algorithm groups nodes by their unique
  9. combinations of node attribute values and edge types with other groups
  10. of nodes to produce a summary graph. The summary graph can then be used to
  11. infer how nodes with different attributes values relate to other nodes in the
  12. graph.
  13. """
  14. import networkx as nx
  15. import matplotlib.pyplot as plt
  16. nodes = {
  17. "A": {"color": "Red"},
  18. "B": {"color": "Red"},
  19. "C": {"color": "Red"},
  20. "D": {"color": "Red"},
  21. "E": {"color": "Blue"},
  22. "F": {"color": "Blue"},
  23. "G": {"color": "Blue"},
  24. "H": {"color": "Blue"},
  25. "I": {"color": "Yellow"},
  26. "J": {"color": "Yellow"},
  27. "K": {"color": "Yellow"},
  28. "L": {"color": "Yellow"},
  29. }
  30. edges = [
  31. ("A", "B", "Strong"),
  32. ("A", "C", "Weak"),
  33. ("A", "E", "Strong"),
  34. ("A", "I", "Weak"),
  35. ("B", "D", "Weak"),
  36. ("B", "J", "Weak"),
  37. ("B", "F", "Strong"),
  38. ("C", "G", "Weak"),
  39. ("D", "H", "Weak"),
  40. ("I", "J", "Strong"),
  41. ("J", "K", "Strong"),
  42. ("I", "L", "Strong"),
  43. ]
  44. original_graph = nx.Graph()
  45. original_graph.add_nodes_from(n for n in nodes.items())
  46. original_graph.add_edges_from((u, v, {"type": label}) for u, v, label in edges)
  47. plt.suptitle("SNAP Summarization")
  48. base_options = {"with_labels": True, "edgecolors": "black", "node_size": 500}
  49. ax1 = plt.subplot(1, 2, 1)
  50. plt.title(
  51. "Original (%s nodes, %s edges)"
  52. % (original_graph.number_of_nodes(), original_graph.number_of_edges())
  53. )
  54. pos = nx.spring_layout(original_graph, seed=7482934)
  55. node_colors = [d["color"] for _, d in original_graph.nodes(data=True)]
  56. edge_type_visual_weight_lookup = {"Weak": 1.0, "Strong": 3.0}
  57. edge_weights = [
  58. edge_type_visual_weight_lookup[d["type"]]
  59. for _, _, d in original_graph.edges(data=True)
  60. ]
  61. nx.draw_networkx(
  62. original_graph, pos=pos, node_color=node_colors, width=edge_weights, **base_options
  63. )
  64. node_attributes = ("color",)
  65. edge_attributes = ("type",)
  66. summary_graph = nx.snap_aggregation(
  67. original_graph, node_attributes, edge_attributes, prefix="S-"
  68. )
  69. plt.subplot(1, 2, 2)
  70. plt.title(
  71. "SNAP Aggregation (%s nodes, %s edges)"
  72. % (summary_graph.number_of_nodes(), summary_graph.number_of_edges())
  73. )
  74. summary_pos = nx.spring_layout(summary_graph, seed=8375428)
  75. node_colors = []
  76. for node in summary_graph:
  77. color = summary_graph.nodes[node]["color"]
  78. node_colors.append(color)
  79. edge_weights = []
  80. for edge in summary_graph.edges():
  81. edge_types = summary_graph.get_edge_data(*edge)["types"]
  82. edge_weight = 0.0
  83. for edge_type in edge_types:
  84. edge_weight += edge_type_visual_weight_lookup[edge_type["type"]]
  85. edge_weights.append(edge_weight)
  86. nx.draw_networkx(
  87. summary_graph,
  88. pos=summary_pos,
  89. node_color=node_colors,
  90. width=edge_weights,
  91. **base_options,
  92. )
  93. plt.tight_layout()
  94. plt.show()