plot_knuth_miles.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/env python
  2. """
  3. ===========
  4. Knuth Miles
  5. ===========
  6. `miles_graph()` returns an undirected graph over the 128 US cities from
  7. the datafile `miles_dat.txt`. The cities each have location and population
  8. data. The edges are labeled with the distance between the two cities.
  9. This example is described in Section 1.1 in Knuth's book (see [1]_ and [2]_).
  10. The data file can be found at:
  11. https://github.com/networkx/networkx/blob/master/examples/drawing/knuth_miles.txt.gz
  12. References.
  13. -----------
  14. .. [1] Donald E. Knuth,
  15. "The Stanford GraphBase: A Platform for Combinatorial Computing",
  16. ACM Press, New York, 1993.
  17. .. [2] http://www-cs-faculty.stanford.edu/~knuth/sgb.html
  18. """
  19. # Author: Aric Hagberg (hagberg@lanl.gov)
  20. # Copyright (C) 2004-2019 by
  21. # Aric Hagberg <hagberg@lanl.gov>
  22. # Dan Schult <dschult@colgate.edu>
  23. # Pieter Swart <swart@lanl.gov>
  24. # All rights reserved.
  25. # BSD license.
  26. import re
  27. import sys
  28. import matplotlib.pyplot as plt
  29. import networkx as nx
  30. def miles_graph():
  31. """ Return the cites example graph in miles_dat.txt
  32. from the Stanford GraphBase.
  33. """
  34. # open file miles_dat.txt.gz (or miles_dat.txt)
  35. import gzip
  36. fh = gzip.open('knuth_miles.txt.gz', 'r')
  37. G = nx.Graph()
  38. G.position = {}
  39. G.population = {}
  40. cities = []
  41. for line in fh.readlines():
  42. line = line.decode()
  43. if line.startswith("*"): # skip comments
  44. continue
  45. numfind = re.compile("^\d+")
  46. if numfind.match(line): # this line is distances
  47. dist = line.split()
  48. for d in dist:
  49. G.add_edge(city, cities[i], weight=int(d))
  50. i = i + 1
  51. else: # this line is a city, position, population
  52. i = 1
  53. (city, coordpop) = line.split("[")
  54. cities.insert(0, city)
  55. (coord, pop) = coordpop.split("]")
  56. (y, x) = coord.split(",")
  57. G.add_node(city)
  58. # assign position - flip x axis for matplotlib, shift origin
  59. G.position[city] = (-int(x) + 7500, int(y) - 3000)
  60. G.population[city] = float(pop) / 1000.0
  61. return G
  62. if __name__ == '__main__':
  63. G = miles_graph()
  64. print("Loaded miles_dat.txt containing 128 cities.")
  65. print("digraph has %d nodes with %d edges"
  66. % (nx.number_of_nodes(G), nx.number_of_edges(G)))
  67. # make new graph of cites, edge if less then 300 miles between them
  68. H = nx.Graph()
  69. for v in G:
  70. H.add_node(v)
  71. for (u, v, pen_weight) in G.edges(data=True):
  72. if pen_weight['weight'] < 300:
  73. H.add_edge(u, v)
  74. # draw with matplotlib/pylab
  75. plt.figure(figsize=(8, 8))
  76. # with nodes colored by degree sized by population
  77. node_color = [float(H.degree(v)) for v in H]
  78. nx.draw(H, G.position,
  79. node_size=[G.population[v] for v in H],
  80. node_color=node_color,
  81. with_labels=False)
  82. # scale the axes equally
  83. plt.xlim(-5000, 500)
  84. plt.ylim(-2000, 3500)
  85. plt.show()