~ubuntu-branches/ubuntu/utopic/python-networkx/utopic

« back to all changes in this revision

Viewing changes to networkx/drawing/nx_pydot.py

  • Committer: Package Import Robot
  • Author(s): Sandro Tosi
  • Date: 2012-08-11 12:41:30 UTC
  • mfrom: (1.4.1) (5.1.13 sid)
  • Revision ID: package-import@ubuntu.com-20120811124130-whr6uso7fncyg8bi
Tags: 1.7-1
* New upstream release
* debian/patches/changeset_*
  - removed, included upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
See Also
11
11
--------
12
 
Pydot: http://www.dkbza.org/pydot.html
 
12
Pydot: http://code.google.com/p/pydot/
13
13
Graphviz:          http://www.research.att.com/sw/tools/graphviz/
14
14
DOT Language:  http://www.graphviz.org/doc/info/lang.html
15
 
 
16
 
 
17
15
"""
18
 
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
19
 
#    Copyright (C) 2004-2008 by 
 
16
#    Copyright (C) 2004-2011 by 
20
17
#    Aric Hagberg <hagberg@lanl.gov>
21
18
#    Dan Schult <dschult@colgate.edu>
22
19
#    Pieter Swart <swart@lanl.gov>
23
20
#    All rights reserved.
24
21
#    BSD license.
25
 
 
 
22
from networkx.utils import open_file, make_str
 
23
import networkx as nx
 
24
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
26
25
__all__ = ['write_dot', 'read_dot', 'graphviz_layout', 'pydot_layout',
27
26
           'to_pydot', 'from_pydot']
28
27
 
29
 
import sys
30
 
from networkx.utils import _get_fh
31
 
import networkx as nx
32
 
 
33
 
 
 
28
@open_file(1,mode='w')
34
29
def write_dot(G,path):
35
30
    """Write NetworkX graph G to Graphviz dot format on path.
36
31
 
39
34
    try:
40
35
        import pydot
41
36
    except ImportError:
42
 
        raise ImportError("write_dot() requires pydot http://dkbza.org/pydot.html/")
43
 
    fh=_get_fh(path,'w')
 
37
        raise ImportError("write_dot() requires pydot",
 
38
                          "http://code.google.com/p/pydot/")
44
39
    P=to_pydot(G)
45
 
    fh.write(P.to_string())
46
 
    fh.flush() # might be a user filehandle so leave open (but flush)
 
40
    path.write(P.to_string())
47
41
    return
48
42
 
 
43
@open_file(0,mode='r')
49
44
def read_dot(path):
50
45
    """Return a NetworkX MultiGraph or MultiDiGraph from a dot file on path.
51
46
 
67
62
        import pydot
68
63
    except ImportError:
69
64
        raise ImportError("read_dot() requires pydot",
70
 
                          "http://dkbza.org/pydot.html/")
 
65
                          "http://code.google.com/p/pydot/")
71
66
 
72
 
    fh=_get_fh(path,'r')
73
 
    data=fh.read()        
 
67
    data=path.read()        
74
68
    P=pydot.graph_from_dot_data(data)
75
69
    return from_pydot(P)
76
70
 
77
 
 
78
71
def from_pydot(P):
79
72
    """Return a NetworkX graph from a Pydot graph.
80
73
 
96
89
    >>> G=nx.Graph(nx.from_pydot(A)) # make a Graph instead of MultiGraph
97
90
 
98
91
    """
99
 
 
100
92
    if P.get_strict(None): # pydot bug: get_strict() shouldn't take argument 
101
93
        multiedges=False
102
94
    else:
116
108
    # assign defaults        
117
109
    N=nx.empty_graph(0,create_using)
118
110
    N.name=P.get_name()
119
 
    node_attr={}
120
111
 
121
112
    # add nodes, attributes to N.node_attr
122
113
    for p in P.get_node_list():
134
125
 
135
126
    # add default attributes for graph, nodes, edges
136
127
    N.graph['graph']=P.get_attributes()
137
 
    # get atributes not working for these?
138
 
    # get_node_defaults()
139
 
    N.graph['node']={}
140
 
    if 'node' in P.obj_dict['nodes']:
141
 
        N.graph['node']=P.obj_dict['nodes']['node'][0]['attributes']
142
 
    # get_edge_defaults()
143
 
    N.graph['edge']={}
144
 
    if 'edge' in P.obj_dict['nodes']:
145
 
        N.graph['edge']=P.obj_dict['nodes']['edge'][0]['attributes']
146
 
    N.node_attr=node_attr
147
 
 
 
128
    try:
 
129
        N.graph['node']=P.get_node_defaults()[0]
 
130
    except:# IndexError,TypeError:
 
131
        N.graph['node']={}
 
132
    try:
 
133
        N.graph['edge']=P.get_edge_defaults()[0]
 
134
    except:# IndexError,TypeError:
 
135
        N.graph['edge']={}
148
136
    return N        
149
137
 
150
138
def to_pydot(N, strict=True):
155
143
    N : NetworkX graph
156
144
      A graph created with NetworkX
157
145
      
158
 
 
159
146
    Examples
160
147
    --------
161
148
    >>> K5=nx.complete_graph(5)
168
155
    try:
169
156
        import pydot
170
157
    except ImportError:
171
 
        raise ImportError("to_pydot() requires pydot http://dkbza.org/pydot.html/")
 
158
        raise ImportError('to_pydot() requires pydot: '
 
159
                          'http://code.google.com/p/pydot/')
172
160
 
173
161
    # set Graphviz graph type
174
162
    if N.is_directed():
176
164
    else:
177
165
        graph_type='graph'
178
166
    strict=N.number_of_selfloops()==0 and not N.is_multigraph() 
179
 
 
180
 
    P = pydot.Dot(graph_type=graph_type,strict=strict)
 
167
    
 
168
    name = N.graph.get('name')
 
169
    graph_defaults=N.graph.get('graph',{})
 
170
    if name is None:
 
171
        P = pydot.Dot(graph_type=graph_type,strict=strict,**graph_defaults)
 
172
    else:
 
173
        P = pydot.Dot('"%s"'%name,graph_type=graph_type,strict=strict,
 
174
                      **graph_defaults)
 
175
    try:
 
176
        P.set_node_defaults(**N.graph['node'])
 
177
    except KeyError:
 
178
        pass
 
179
    try:
 
180
        P.set_edge_defaults(**N.graph['edge'])
 
181
    except KeyError:
 
182
        pass
181
183
 
182
184
    for n,nodedata in N.nodes_iter(data=True):
183
 
        str_nodedata=dict((k,str(v)) for k,v in nodedata.items())
184
 
        p=pydot.Node(str(n),**str_nodedata)
 
185
        str_nodedata=dict((k,make_str(v)) for k,v in nodedata.items())
 
186
        p=pydot.Node(make_str(n),**str_nodedata)
185
187
        P.add_node(p)
186
188
 
187
189
    if N.is_multigraph():
188
190
        for u,v,key,edgedata in N.edges_iter(data=True,keys=True):
189
 
            str_edgedata=dict((k,str(v)) for k,v in edgedata.items())
190
 
            edge=pydot.Edge(str(u),str(v),key=str(key),**str_edgedata)
 
191
            str_edgedata=dict((k,make_str(v)) for k,v in edgedata.items())
 
192
            edge=pydot.Edge(make_str(u),make_str(v),key=make_str(key),**str_edgedata)
191
193
            P.add_edge(edge)
192
194
        
193
195
    else:
194
196
        for u,v,edgedata in N.edges_iter(data=True):
195
 
            str_edgedata=dict((k,str(v)) for k,v in edgedata.items())
196
 
            edge=pydot.Edge(str(u),str(v),**str_edgedata)
 
197
            str_edgedata=dict((k,make_str(v)) for k,v in edgedata.items())
 
198
            edge=pydot.Edge(make_str(u),make_str(v),**str_edgedata)
197
199
            P.add_edge(edge)
198
200
 
199
 
    try:
200
 
        P.obj_dict['attributes'].update(N.graph.get('graph',{}))
201
 
    except:
202
 
        pass
203
 
    try:
204
 
        P.obj_dict['nodes']['node'][0]['attributes'].update(N.graph.get('node',{}))
205
 
    except:
206
 
        pass
207
 
    try:
208
 
        P.obj_dict['nodes']['edge'][0]['attributes'].update(N.graph.get('edge',{}))
209
 
    except:
210
 
        pass
211
 
 
212
201
    return P
213
202
 
214
203
 
259
248
    try:
260
249
        import pydot
261
250
    except ImportError:
262
 
        raise ImportError("pydot_layout() requires pydot http://dkbza.org/pydot.html/")
 
251
        raise ImportError('pydot_layout() requires pydot ',
 
252
                          'http://code.google.com/p/pydot/')
263
253
 
264
254
    P=to_pydot(G)
265
255
    if root is not None :
266
 
        P.set("root",str(root))
 
256
        P.set("root",make_str(root))
267
257
 
268
258
    D=P.create_dot(prog=prog)
269
259
 
280
270
 
281
271
    node_pos={}
282
272
    for n in G.nodes():
283
 
        node=Q.get_node(pydot.Node(n).get_name())
 
273
        pydot_node = pydot.Node(make_str(n)).get_name().encode('utf-8')
 
274
        node=Q.get_node(pydot_node)
 
275
 
 
276
        if isinstance(node,list):
 
277
            node=node[0]
284
278
        pos=node.get_pos()[1:-1] # strip leading and trailing double quotes
285
279
        if pos != None:
286
280
            xx,yy=pos.split(",")