Package networkx :: Package drawing :: Module nx_agraph
[hide private]
[frames] | no frames]

Source Code for Module networkx.drawing.nx_agraph

  1  """ 
  2  Interface to pygraphviz AGraph class. 
  3   
  4  Usage  
  5   
  6   >>> from networkx import * 
  7   >>> G=complete_graph(5) 
  8   >>> A=to_agraph(G) 
  9   >>> H=from_agraph(A) 
 10   
 11  """ 
 12  __author__ = """Aric Hagberg (hagberg@lanl.gov)""" 
 13  #    Copyright (C) 2004-2006 by  
 14  #    Aric Hagberg <hagberg@lanl.gov> 
 15  #    Dan Schult <dschult@colgate.edu> 
 16  #    Pieter Swart <swart@lanl.gov> 
 17  #    Distributed under the terms of the GNU Lesser General Public License 
 18  #    http://www.gnu.org/copyleft/lesser.html 
 19  import os 
 20  import sys 
 21  from networkx.utils import _get_fh 
 22  try: 
 23      import pygraphviz 
 24  except ImportError: 
 25      raise 
 26   
27 -def from_agraph(A,create_using=None):
28 """Return a NetworkX XGraph or XDiGraph from a pygraphviz graph. 29 30 >>> X=from_agraph(A) 31 32 The XGraph X will have a dictionary X.graph_attr containing 33 the default graphviz attributes for graphs, nodes and edges. 34 35 Default node attributes will be in the dictionary X.node_attr 36 which is keyed by node. 37 38 Edge attributes will be returned as edge data in the graph X. 39 40 If you want a Graph with no attributes attached instead of an XGraph 41 with attributes use 42 43 >>> G=Graph(X) 44 45 """ 46 import networkx 47 if A.is_strict(): 48 multiedges=False 49 selfloops=False 50 else: 51 multiedges=True 52 selfloops=True 53 54 if create_using is None: 55 if A.is_undirected(): 56 create_using=networkx.XGraph(multiedges=multiedges, 57 selfloops=selfloops) 58 else: 59 create_using=networkx.XDiGraph(multiedges=multiedges, 60 selfloops=selfloops) 61 62 # assign defaults 63 N=networkx.empty_graph(0,create_using) 64 N.name=str(A) 65 node_attr={} 66 # add nodes, attributes to N.node_attr 67 for n in A.nodes(): 68 N.add_node(n) 69 node_attr[n]=n.attr 70 71 # add edges, attributes attached to edge 72 for e in A.edges(): 73 if len(e)==2: 74 u,v=e 75 else: 76 u,v,k=e 77 if hasattr(N,'allow_multiedges')==True: # XGraph 78 N.add_edge(u,v,e.attr) 79 else: # Graph 80 N.add_edge(u,v) 81 82 # add default attributes for graph, nodes, and edges 83 # hang them on N.graph_attr 84 if hasattr(N,'allow_multiedges')==True: # XGraph 85 N.graph_attr={} 86 N.graph_attr['graph']=A.graph_attr 87 N.graph_attr['node']=A.node_attr 88 N.graph_attr['edge']=A.edge_attr 89 N.node_attr=node_attr 90 91 return N
92
93 -def to_agraph(N, graph_attr=None, node_attr=None, edge_attr=None, 94 strict=True):
95 """Return a pygraphviz graph from a NetworkX graph N. 96 97 If N is a Graph or DiGraph, graphviz attributes can 98 be supplied through the arguments 99 100 graph_attr: dictionary with default attributes for graph, nodes, and edges 101 keyed by 'graph', 'node', and 'edge' to attribute dictionaries 102 103 node_attr: dictionary keyed by node to node attribute dictionary 104 105 edge_attr: dictionary keyed by edge tuple to edge attribute dictionary 106 107 If N is an XGraph or XDiGraph an attempt will be made first 108 to copy properties attached to the graph (see from_agraph) 109 and then updated with the calling arguments if any. 110 111 """ 112 directed=N.is_directed() 113 if hasattr(N,'allow_multiedges'): 114 if N.multiedges: 115 strict=False 116 if hasattr(N,'allow_selfloops'): 117 if N.selfloops: 118 strict=False 119 A=pygraphviz.AGraph(name=N.name,strict=strict,directed=directed) 120 121 # default graph attributes 122 try: 123 A.graph_attr.update(N.graph_attr['graph']) 124 except: 125 pass 126 try: 127 A.graph_attr.update(graph_attr['graph']) 128 except: 129 pass 130 # default node attributes 131 try: 132 A.node_attr.update(N.graph_attr['node']) 133 except: 134 pass 135 try: 136 A.node_attr.update(graph_attr['node']) 137 except: 138 pass 139 # default edge attributes 140 try: 141 A.edge_attr.update(N.graph_attr['edge']) 142 except: 143 pass 144 try: 145 A.edge_attr.update(graph_attr['edge']) 146 except: 147 pass 148 149 # add nodes 150 for n in N.nodes_iter(): 151 A.add_node(n) 152 node=pygraphviz.Node(A,n) 153 # try node attributes attached to graph 154 try: 155 if n in N.node_attr: 156 node.attr.update(N.node_attr[n]) 157 except: 158 pass 159 # update with attributes from calling parameters 160 try: 161 if n in node_attr: 162 node.attr.update(node_attr[n]) 163 except: 164 pass 165 166 # loop over edges 167 for e in N.edges_iter(): 168 if len(e)==2: 169 (u,v)=e 170 data=None 171 else: 172 (u,v,data)=e 173 174 if data is None: # no data, just add edge 175 A.add_edge(u,v) 176 edge=pygraphviz.Edge(A,u,v) 177 else: # could have list of edge data or single edge data 178 try: 179 N.allow_multiedges()==True 180 dlist=N.get_edge(u,v) 181 except: 182 dlist=[N.get_edge(u,v)] 183 for d in dlist: 184 A.add_edge(u,v) 185 edge=pygraphviz.Edge(A,u,v) 186 if hasattr(d,"__getitem__"): 187 edge.attr.update(d) 188 # update from calling argument 189 try: # e might not be hashable 190 if (u,v) in edge_attr: 191 edge.attr.update(edge_attr[(u,v)]) 192 except: 193 pass 194 195 return A
196
197 -def write_dot(G,path):
198 """Write NetworkX graph G to Graphviz dot format on path. 199 200 Path can be a string or a file handle. 201 """ 202 A=to_agraph(G) 203 A.write(path) 204 return
205
206 -def read_dot(path,create_using=None):
207 """Return a NetworkX XGraph or XdiGraph from a dot file on path. 208 209 Path can be a string or a file handle. 210 211 """ 212 A=pygraphviz.AGraph(file=path) 213 return from_agraph(A)
214 215
216 -def graphviz_layout(G,prog='neato',root=None, args=''):
217 """ 218 Create layout using graphviz. 219 Returns a dictionary of positions keyed by node. 220 221 >>> from networkx import * 222 >>> G=petersen_graph() 223 >>> pos=graphviz_layout(G) 224 >>> pos=graphviz_layout(G,prog='dot') 225 226 This is a wrapper for pygraphviz_layout. 227 228 """ 229 return pygraphviz_layout(G,prog=prog,root=root,args=args)
230
231 -def pygraphviz_layout(G,prog='neato',root=None, args=''):
232 """ 233 Create layout using pygraphviz and graphviz. 234 Returns a dictionary of positions keyed by node. 235 236 >>> from networkx import * 237 >>> G=petersen_graph() 238 >>> pos=pygraphviz_layout(G) 239 >>> pos=pygraphviz_layout(G,prog='dot') 240 241 """ 242 A=to_agraph(G) 243 A.layout(prog=prog,args=args) 244 node_pos={} 245 for n in G.nodes(): 246 node=pygraphviz.Node(A,n) 247 try: 248 xx,yy=node.attr["pos"].split(',') 249 node_pos[n]=(float(xx),float(yy)) 250 except: 251 print "no position for node",n 252 node_pos[n]=(0.0,0.0) 253 return node_pos
254 255
256 -def _test_suite():
257 import doctest 258 suite = doctest.DocFileSuite('tests/drawing/nx_agraph.txt',package='networkx') 259 return suite
260 261 262 263 264 if __name__ == "__main__": 265 import os 266 import sys 267 import unittest 268 if sys.version_info[:2] < (2, 4): 269 print "Python version 2.4 or later required for tests (%d.%d detected)." % sys.version_info[:2] 270 sys.exit(-1) 271 # directory of networkx package (relative to this) 272 nxbase=sys.path[0]+os.sep+os.pardir 273 sys.path.insert(0,nxbase) # prepend to search path 274 unittest.TextTestRunner().run(_test_suite()) 275