Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/networkx/readwrite/pajek.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author | shellac |
---|---|
date | Mon, 01 Jun 2020 08:59:25 -0400 |
parents | 79f47841a781 |
children |
comparison
equal
deleted
inserted
replaced
4:79f47841a781 | 5:9b1c78e6ba9c |
---|---|
1 # Copyright (C) 2008-2014 by | |
2 # Aric Hagberg <hagberg@lanl.gov> | |
3 # Dan Schult <dschult@colgate.edu> | |
4 # Pieter Swart <swart@lanl.gov> | |
5 # All rights reserved. | |
6 # BSD license. | |
7 # | |
8 # Authors: Aric Hagberg (hagberg@lanl.gov) | |
9 """ | |
10 ***** | |
11 Pajek | |
12 ***** | |
13 Read graphs in Pajek format. | |
14 | |
15 This implementation handles directed and undirected graphs including | |
16 those with self loops and parallel edges. | |
17 | |
18 Format | |
19 ------ | |
20 See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm | |
21 for format information. | |
22 | |
23 """ | |
24 | |
25 import warnings | |
26 | |
27 import networkx as nx | |
28 from networkx.utils import is_string_like, open_file, make_str | |
29 | |
30 __all__ = ['read_pajek', 'parse_pajek', 'generate_pajek', 'write_pajek'] | |
31 | |
32 | |
33 def generate_pajek(G): | |
34 """Generate lines in Pajek graph format. | |
35 | |
36 Parameters | |
37 ---------- | |
38 G : graph | |
39 A Networkx graph | |
40 | |
41 References | |
42 ---------- | |
43 See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm | |
44 for format information. | |
45 """ | |
46 if G.name == '': | |
47 name = 'NetworkX' | |
48 else: | |
49 name = G.name | |
50 # Apparently many Pajek format readers can't process this line | |
51 # So we'll leave it out for now. | |
52 # yield '*network %s'%name | |
53 | |
54 # write nodes with attributes | |
55 yield '*vertices %s' % (G.order()) | |
56 nodes = list(G) | |
57 # make dictionary mapping nodes to integers | |
58 nodenumber = dict(zip(nodes, range(1, len(nodes) + 1))) | |
59 for n in nodes: | |
60 # copy node attributes and pop mandatory attributes | |
61 # to avoid duplication. | |
62 na = G.nodes.get(n, {}).copy() | |
63 x = na.pop('x', 0.0) | |
64 y = na.pop('y', 0.0) | |
65 id = int(na.pop('id', nodenumber[n])) | |
66 nodenumber[n] = id | |
67 shape = na.pop('shape', 'ellipse') | |
68 s = ' '.join(map(make_qstr, (id, n, x, y, shape))) | |
69 # only optional attributes are left in na. | |
70 for k, v in na.items(): | |
71 if is_string_like(v) and v.strip() != '': | |
72 s += ' %s %s' % (make_qstr(k), make_qstr(v)) | |
73 else: | |
74 warnings.warn('Node attribute %s is not processed. %s.' % | |
75 (k, | |
76 'Empty attribute' if is_string_like(v) else | |
77 'Non-string attribute')) | |
78 yield s | |
79 | |
80 # write edges with attributes | |
81 if G.is_directed(): | |
82 yield '*arcs' | |
83 else: | |
84 yield '*edges' | |
85 for u, v, edgedata in G.edges(data=True): | |
86 d = edgedata.copy() | |
87 value = d.pop('weight', 1.0) # use 1 as default edge value | |
88 s = ' '.join(map(make_qstr, (nodenumber[u], nodenumber[v], value))) | |
89 for k, v in d.items(): | |
90 if is_string_like(v) and v.strip() != '': | |
91 s += ' %s %s' % (make_qstr(k), make_qstr(v)) | |
92 else: | |
93 warnings.warn('Edge attribute %s is not processed. %s.' % | |
94 (k, | |
95 'Empty attribute' if is_string_like(v) else | |
96 'Non-string attribute')) | |
97 yield s | |
98 | |
99 | |
100 @open_file(1, mode='wb') | |
101 def write_pajek(G, path, encoding='UTF-8'): | |
102 """Write graph in Pajek format to path. | |
103 | |
104 Parameters | |
105 ---------- | |
106 G : graph | |
107 A Networkx graph | |
108 path : file or string | |
109 File or filename to write. | |
110 Filenames ending in .gz or .bz2 will be compressed. | |
111 | |
112 Examples | |
113 -------- | |
114 >>> G=nx.path_graph(4) | |
115 >>> nx.write_pajek(G, "test.net") | |
116 | |
117 Warnings | |
118 -------- | |
119 Optional node attributes and edge attributes must be non-empty strings. | |
120 Otherwise it will not be written into the file. You will need to | |
121 convert those attributes to strings if you want to keep them. | |
122 | |
123 References | |
124 ---------- | |
125 See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm | |
126 for format information. | |
127 """ | |
128 for line in generate_pajek(G): | |
129 line += '\n' | |
130 path.write(line.encode(encoding)) | |
131 | |
132 | |
133 @open_file(0, mode='rb') | |
134 def read_pajek(path, encoding='UTF-8'): | |
135 """Read graph in Pajek format from path. | |
136 | |
137 Parameters | |
138 ---------- | |
139 path : file or string | |
140 File or filename to write. | |
141 Filenames ending in .gz or .bz2 will be uncompressed. | |
142 | |
143 Returns | |
144 ------- | |
145 G : NetworkX MultiGraph or MultiDiGraph. | |
146 | |
147 Examples | |
148 -------- | |
149 >>> G=nx.path_graph(4) | |
150 >>> nx.write_pajek(G, "test.net") | |
151 >>> G=nx.read_pajek("test.net") | |
152 | |
153 To create a Graph instead of a MultiGraph use | |
154 | |
155 >>> G1=nx.Graph(G) | |
156 | |
157 References | |
158 ---------- | |
159 See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm | |
160 for format information. | |
161 """ | |
162 lines = (line.decode(encoding) for line in path) | |
163 return parse_pajek(lines) | |
164 | |
165 | |
166 def parse_pajek(lines): | |
167 """Parse Pajek format graph from string or iterable. | |
168 | |
169 Parameters | |
170 ---------- | |
171 lines : string or iterable | |
172 Data in Pajek format. | |
173 | |
174 Returns | |
175 ------- | |
176 G : NetworkX graph | |
177 | |
178 See Also | |
179 -------- | |
180 read_pajek() | |
181 | |
182 """ | |
183 import shlex | |
184 # multigraph=False | |
185 if is_string_like(lines): | |
186 lines = iter(lines.split('\n')) | |
187 lines = iter([line.rstrip('\n') for line in lines]) | |
188 G = nx.MultiDiGraph() # are multiedges allowed in Pajek? assume yes | |
189 labels = [] # in the order of the file, needed for matrix | |
190 while lines: | |
191 try: | |
192 l = next(lines) | |
193 except: # EOF | |
194 break | |
195 if l.lower().startswith("*network"): | |
196 try: | |
197 label, name = l.split(None, 1) | |
198 except ValueError: | |
199 # Line was not of the form: *network NAME | |
200 pass | |
201 else: | |
202 G.graph['name'] = name | |
203 elif l.lower().startswith("*vertices"): | |
204 nodelabels = {} | |
205 l, nnodes = l.split() | |
206 for i in range(int(nnodes)): | |
207 l = next(lines) | |
208 try: | |
209 splitline = [x.decode('utf-8') for x in | |
210 shlex.split(make_str(l).encode('utf-8'))] | |
211 except AttributeError: | |
212 splitline = shlex.split(str(l)) | |
213 id, label = splitline[0:2] | |
214 labels.append(label) | |
215 G.add_node(label) | |
216 nodelabels[id] = label | |
217 G.nodes[label]['id'] = id | |
218 try: | |
219 x, y, shape = splitline[2:5] | |
220 G.nodes[label].update({'x': float(x), | |
221 'y': float(y), | |
222 'shape': shape}) | |
223 except: | |
224 pass | |
225 extra_attr = zip(splitline[5::2], splitline[6::2]) | |
226 G.nodes[label].update(extra_attr) | |
227 elif l.lower().startswith("*edges") or l.lower().startswith("*arcs"): | |
228 if l.lower().startswith("*edge"): | |
229 # switch from multidigraph to multigraph | |
230 G = nx.MultiGraph(G) | |
231 if l.lower().startswith("*arcs"): | |
232 # switch to directed with multiple arcs for each existing edge | |
233 G = G.to_directed() | |
234 for l in lines: | |
235 try: | |
236 splitline = [x.decode('utf-8') for x in | |
237 shlex.split(make_str(l).encode('utf-8'))] | |
238 except AttributeError: | |
239 splitline = shlex.split(str(l)) | |
240 | |
241 if len(splitline) < 2: | |
242 continue | |
243 ui, vi = splitline[0:2] | |
244 u = nodelabels.get(ui, ui) | |
245 v = nodelabels.get(vi, vi) | |
246 # parse the data attached to this edge and put in a dictionary | |
247 edge_data = {} | |
248 try: | |
249 # there should always be a single value on the edge? | |
250 w = splitline[2:3] | |
251 edge_data.update({'weight': float(w[0])}) | |
252 except: | |
253 pass | |
254 # if there isn't, just assign a 1 | |
255 # edge_data.update({'value':1}) | |
256 extra_attr = zip(splitline[3::2], splitline[4::2]) | |
257 edge_data.update(extra_attr) | |
258 # if G.has_edge(u,v): | |
259 # multigraph=True | |
260 G.add_edge(u, v, **edge_data) | |
261 elif l.lower().startswith("*matrix"): | |
262 G = nx.DiGraph(G) | |
263 adj_list = ((labels[row], labels[col], {'weight': int(data)}) | |
264 for (row, line) in enumerate(lines) | |
265 for (col, data) in enumerate(line.split()) | |
266 if int(data) != 0) | |
267 G.add_edges_from(adj_list) | |
268 | |
269 return G | |
270 | |
271 | |
272 def make_qstr(t): | |
273 """Returns the string representation of t. | |
274 Add outer double-quotes if the string has a space. | |
275 """ | |
276 if not is_string_like(t): | |
277 t = str(t) | |
278 if " " in t: | |
279 t = r'"%s"' % t | |
280 return t | |
281 | |
282 | |
283 # fixture for pytest | |
284 def teardown_module(module): | |
285 import os | |
286 os.unlink('test.net') |