text: #!/usr/bin/env python
  
  """
  An example of the MultiDiGraph clas
  
  The function chess_pgn_graph reads a collection of chess 
  matches stored in the specified PGN file 
  (PGN ="Portable Game Notation")
  Here the (compressed) default file ---
   chess_masters_WCC.pgn.bz2 ---
  contains all 685 World Chess Championship matches
  from 1886 - 1985.
  (data from http://chessproblem.my-free-games.com/chess/games/Download-PGN.php)
  
  The chess_pgn_graph() function returns a MultiDiGraph 
  with multiple edges. Each node is 
  the last name of a chess master. Each edge is directed 
  from white to black and contains selected game info.
  
  The key statement in chess_pgn_graph below is
      G.add_edge(white, black, game_info)
  where game_info is a dict describing each game.
  
  """
  #    Copyright (C) 2006-2010 by 
  #    Aric Hagberg <hagberg@lanl.gov>
  #    Dan Schult <dschult@colgate.edu>
  #    Pieter Swart <swart@lanl.gov>
  #    All rights reserved.
  #    BSD license.
  
  import networkx as nx
  
  # tag names specifying what game info should be 
  # stored in the dict on each digraph edge
  game_details=["Event", 
                "Date", 
                "Result", 
                "ECO",
                "Site"]
  
  def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"):
      """Read chess games in pgn format in pgn_file.
      
      Filenames ending in .gz or .bz2 will be uncompressed.
      
      Return the MultiDiGraph of players connected by a chess game.
      Edges contain game data in a dict.
  
      """
      import bz2
      G=nx.MultiDiGraph()
      game={}
      datafile = bz2.BZ2File(pgn_file)
      lines = (line.decode().rstrip('\r\n') for line in datafile)
      for line in lines:
          if line.startswith('['):
              tag,value=line[1:-1].split(' ',1)
              game[str(tag)]=value.strip('"')
          else:
          # empty line after tag set indicates 
          # we finished reading game info
              if game:
                  white=game.pop('White')
                  black=game.pop('Black')
                  G.add_edge(white, black, **game)
                  game={}
      return G
  
  
  if __name__ == '__main__':
      import networkx as nx
  
  
      G=chess_pgn_graph()
  
      ngames=G.number_of_edges()
      nplayers=G.number_of_nodes()
  
      print("Loaded %d chess games between %d players\n"\
                     % (ngames,nplayers))
  
      # identify connected components
      # of the undirected version
      Gcc=nx.connected_component_subgraphs(G.to_undirected())
      if len(Gcc)>1:
          print("Note the disconnected component consisting of:")
          print(Gcc[1].nodes())    
  
      # find all games with B97 opening (as described in ECO)
      openings=set([game_info['ECO'] 
                    for (white,black,game_info) in G.edges(data=True)])
      print("\nFrom a total of %d different openings,"%len(openings))
      print('the following games used the Sicilian opening')
      print('with the Najdorff 7...Qb6 "Poisoned Pawn" variation.\n')
  
      for (white,black,game_info) in G.edges(data=True):
          if game_info['ECO']=='B97':
             print(white,"vs",black)
             for k,v in game_info.items():
                 print("   ",k,": ",v)
             print("\n")
  
  
      try:
          import matplotlib.pyplot as plt
      except ImportError:
          import sys
          print("Matplotlib needed for drawing. Skipping")
          sys.exit(0)
  
      # make new undirected graph H without multi-edges
      H=nx.Graph(G)
  
      # edge width is proportional number of games played
      edgewidth=[]
      for (u,v,d) in H.edges(data=True):
          edgewidth.append(len(G.get_edge_data(u,v)))
  
      # node size is proportional to number of games won
      wins=dict.fromkeys(G.nodes(),0.0)
      for (u,v,d) in G.edges(data=True):
          r=d['Result'].split('-')
          if r[0]=='1':
              wins[u]+=1.0
          elif r[0]=='1/2':
              wins[u]+=0.5
              wins[v]+=0.5
          else:
              wins[v]+=1.0
      try:
          pos=nx.graphviz_layout(H)
      except:
          pos=nx.spring_layout(H,iterations=20)
  
      plt.rcParams['text.usetex'] = False
      plt.figure(figsize=(8,8))
      nx.draw_networkx_edges(H,pos,alpha=0.3,width=edgewidth, edge_color='m')
      nodesize=[wins[v]*50 for v in H]
      nx.draw_networkx_nodes(H,pos,node_size=nodesize,node_color='w',alpha=0.4)
      nx.draw_networkx_edges(H,pos,alpha=0.4,node_size=0,width=1,edge_color='k')
      nx.draw_networkx_labels(H,pos,fontsize=14)
      font = {'fontname'   : 'Helvetica',
              'color'      : 'k',
              'fontweight' : 'bold',
              'fontsize'   : 14}
      plt.title("World Chess Championship Games: 1886 - 1985", font)
  
      # change font and write text (using data coordinates)
      font = {'fontname'   : 'Helvetica',
      'color'      : 'r',
      'fontweight' : 'bold',
      'fontsize'   : 14}
  
      plt.text(0.5, 0.97, "edge width = # games played",
               horizontalalignment='center',
               transform=plt.gca().transAxes)
      plt.text(0.5, 0.94,  "node size = # games won",
               horizontalalignment='center',
               transform=plt.gca().transAxes)
  
      plt.axis('off')
      plt.savefig("chess_masters.png",dpi=75)
      print("Wrote chess_masters.png")
      plt.show() # display
  