plot_unix_email.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """
  2. ==========
  3. Unix Email
  4. ==========
  5. Create a directed graph, allowing multiple edges and self loops, from a unix
  6. mailbox. The nodes are email addresses with links that point from the sender
  7. to the receivers. The edge data is a Python email.Message object which
  8. contains all of the email message data.
  9. This example shows the power of `DiGraph` to hold edge data of arbitrary Python
  10. objects (in this case a list of email messages).
  11. The sample unix email mailbox called "unix_email.mbox" may be found here:
  12. - https://github.com/networkx/networkx/blob/main/examples/drawing/unix_email.mbox
  13. """
  14. from email.utils import getaddresses, parseaddr
  15. import mailbox
  16. import matplotlib.pyplot as plt
  17. import networkx as nx
  18. # unix mailbox recipe
  19. # see https://docs.python.org/3/library/mailbox.html
  20. def mbox_graph():
  21. mbox = mailbox.mbox("unix_email.mbox") # parse unix mailbox
  22. G = nx.MultiDiGraph() # create empty graph
  23. # parse each messages and build graph
  24. for msg in mbox: # msg is python email.Message.Message object
  25. (source_name, source_addr) = parseaddr(msg["From"]) # sender
  26. # get all recipients
  27. # see https://docs.python.org/3/library/email.html
  28. tos = msg.get_all("to", [])
  29. ccs = msg.get_all("cc", [])
  30. resent_tos = msg.get_all("resent-to", [])
  31. resent_ccs = msg.get_all("resent-cc", [])
  32. all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
  33. # now add the edges for this mail message
  34. for target_name, target_addr in all_recipients:
  35. G.add_edge(source_addr, target_addr, message=msg)
  36. return G
  37. G = mbox_graph()
  38. # print edges with message subject
  39. for u, v, d in G.edges(data=True):
  40. print(f"From: {u} To: {v} Subject: {d['message']['Subject']}")
  41. pos = nx.spring_layout(G, iterations=10, seed=227)
  42. nx.draw(G, pos, node_size=0, alpha=0.4, edge_color="r", font_size=16, with_labels=True)
  43. ax = plt.gca()
  44. ax.margins(0.08)
  45. plt.show()