Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/networkx/readwrite/pajek.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
| author | shellac |
|---|---|
| date | Sat, 02 May 2020 07:14:21 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:26e78fe6e8c4 |
|---|---|
| 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') |
