Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/networkx/drawing/nx_pylab.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """ | |
2 ********** | |
3 Matplotlib | |
4 ********** | |
5 | |
6 Draw networks with matplotlib. | |
7 | |
8 See Also | |
9 -------- | |
10 | |
11 matplotlib: http://matplotlib.org/ | |
12 | |
13 pygraphviz: http://pygraphviz.github.io/ | |
14 | |
15 """ | |
16 from numbers import Number | |
17 import networkx as nx | |
18 from networkx.drawing.layout import ( | |
19 shell_layout, | |
20 circular_layout, | |
21 kamada_kawai_layout, | |
22 spectral_layout, | |
23 spring_layout, | |
24 random_layout, | |
25 planar_layout, | |
26 ) | |
27 | |
28 __all__ = [ | |
29 "draw", | |
30 "draw_networkx", | |
31 "draw_networkx_nodes", | |
32 "draw_networkx_edges", | |
33 "draw_networkx_labels", | |
34 "draw_networkx_edge_labels", | |
35 "draw_circular", | |
36 "draw_kamada_kawai", | |
37 "draw_random", | |
38 "draw_spectral", | |
39 "draw_spring", | |
40 "draw_planar", | |
41 "draw_shell", | |
42 ] | |
43 | |
44 | |
45 def draw(G, pos=None, ax=None, **kwds): | |
46 """Draw the graph G with Matplotlib. | |
47 | |
48 Draw the graph as a simple representation with no node | |
49 labels or edge labels and using the full Matplotlib figure area | |
50 and no axis labels by default. See draw_networkx() for more | |
51 full-featured drawing that allows title, axis labels etc. | |
52 | |
53 Parameters | |
54 ---------- | |
55 G : graph | |
56 A networkx graph | |
57 | |
58 pos : dictionary, optional | |
59 A dictionary with nodes as keys and positions as values. | |
60 If not specified a spring layout positioning will be computed. | |
61 See :py:mod:`networkx.drawing.layout` for functions that | |
62 compute node positions. | |
63 | |
64 ax : Matplotlib Axes object, optional | |
65 Draw the graph in specified Matplotlib axes. | |
66 | |
67 kwds : optional keywords | |
68 See networkx.draw_networkx() for a description of optional keywords. | |
69 | |
70 Examples | |
71 -------- | |
72 >>> G = nx.dodecahedral_graph() | |
73 >>> nx.draw(G) | |
74 >>> nx.draw(G, pos=nx.spring_layout(G)) # use spring layout | |
75 | |
76 See Also | |
77 -------- | |
78 draw_networkx() | |
79 draw_networkx_nodes() | |
80 draw_networkx_edges() | |
81 draw_networkx_labels() | |
82 draw_networkx_edge_labels() | |
83 | |
84 Notes | |
85 ----- | |
86 This function has the same name as pylab.draw and pyplot.draw | |
87 so beware when using `from networkx import *` | |
88 | |
89 since you might overwrite the pylab.draw function. | |
90 | |
91 With pyplot use | |
92 | |
93 >>> import matplotlib.pyplot as plt | |
94 >>> G = nx.dodecahedral_graph() | |
95 >>> nx.draw(G) # networkx draw() | |
96 >>> plt.draw() # pyplot draw() | |
97 | |
98 Also see the NetworkX drawing examples at | |
99 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
100 """ | |
101 try: | |
102 import matplotlib.pyplot as plt | |
103 except ImportError as e: | |
104 raise ImportError("Matplotlib required for draw()") from e | |
105 except RuntimeError: | |
106 print("Matplotlib unable to open display") | |
107 raise | |
108 | |
109 if ax is None: | |
110 cf = plt.gcf() | |
111 else: | |
112 cf = ax.get_figure() | |
113 cf.set_facecolor("w") | |
114 if ax is None: | |
115 if cf._axstack() is None: | |
116 ax = cf.add_axes((0, 0, 1, 1)) | |
117 else: | |
118 ax = cf.gca() | |
119 | |
120 if "with_labels" not in kwds: | |
121 kwds["with_labels"] = "labels" in kwds | |
122 | |
123 draw_networkx(G, pos=pos, ax=ax, **kwds) | |
124 ax.set_axis_off() | |
125 plt.draw_if_interactive() | |
126 return | |
127 | |
128 | |
129 def draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds): | |
130 """Draw the graph G using Matplotlib. | |
131 | |
132 Draw the graph with Matplotlib with options for node positions, | |
133 labeling, titles, and many other drawing features. | |
134 See draw() for simple drawing without labels or axes. | |
135 | |
136 Parameters | |
137 ---------- | |
138 G : graph | |
139 A networkx graph | |
140 | |
141 pos : dictionary, optional | |
142 A dictionary with nodes as keys and positions as values. | |
143 If not specified a spring layout positioning will be computed. | |
144 See :py:mod:`networkx.drawing.layout` for functions that | |
145 compute node positions. | |
146 | |
147 arrows : bool, optional (default=True) | |
148 For directed graphs, if True draw arrowheads. | |
149 Note: Arrows will be the same color as edges. | |
150 | |
151 arrowstyle : str, optional (default='-|>') | |
152 For directed graphs, choose the style of the arrowsheads. | |
153 See :py:class: `matplotlib.patches.ArrowStyle` for more | |
154 options. | |
155 | |
156 arrowsize : int, optional (default=10) | |
157 For directed graphs, choose the size of the arrow head head's length and | |
158 width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute | |
159 `mutation_scale` for more info. | |
160 | |
161 with_labels : bool, optional (default=True) | |
162 Set to True to draw labels on the nodes. | |
163 | |
164 ax : Matplotlib Axes object, optional | |
165 Draw the graph in the specified Matplotlib axes. | |
166 | |
167 nodelist : list, optional (default G.nodes()) | |
168 Draw only specified nodes | |
169 | |
170 edgelist : list, optional (default=G.edges()) | |
171 Draw only specified edges | |
172 | |
173 node_size : scalar or array, optional (default=300) | |
174 Size of nodes. If an array is specified it must be the | |
175 same length as nodelist. | |
176 | |
177 node_color : color or array of colors (default='#1f78b4') | |
178 Node color. Can be a single color or a sequence of colors with the same | |
179 length as nodelist. Color can be string, or rgb (or rgba) tuple of | |
180 floats from 0-1. If numeric values are specified they will be | |
181 mapped to colors using the cmap and vmin,vmax parameters. See | |
182 matplotlib.scatter for more details. | |
183 | |
184 node_shape : string, optional (default='o') | |
185 The shape of the node. Specification is as matplotlib.scatter | |
186 marker, one of 'so^>v<dph8'. | |
187 | |
188 alpha : float, optional (default=None) | |
189 The node and edge transparency | |
190 | |
191 cmap : Matplotlib colormap, optional (default=None) | |
192 Colormap for mapping intensities of nodes | |
193 | |
194 vmin,vmax : float, optional (default=None) | |
195 Minimum and maximum for node colormap scaling | |
196 | |
197 linewidths : [None | scalar | sequence] | |
198 Line width of symbol border (default =1.0) | |
199 | |
200 width : float, optional (default=1.0) | |
201 Line width of edges | |
202 | |
203 edge_color : color or array of colors (default='k') | |
204 Edge color. Can be a single color or a sequence of colors with the same | |
205 length as edgelist. Color can be string, or rgb (or rgba) tuple of | |
206 floats from 0-1. If numeric values are specified they will be | |
207 mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters. | |
208 | |
209 edge_cmap : Matplotlib colormap, optional (default=None) | |
210 Colormap for mapping intensities of edges | |
211 | |
212 edge_vmin,edge_vmax : floats, optional (default=None) | |
213 Minimum and maximum for edge colormap scaling | |
214 | |
215 style : string, optional (default='solid') | |
216 Edge line style (solid|dashed|dotted,dashdot) | |
217 | |
218 labels : dictionary, optional (default=None) | |
219 Node labels in a dictionary keyed by node of text labels | |
220 | |
221 font_size : int, optional (default=12) | |
222 Font size for text labels | |
223 | |
224 font_color : string, optional (default='k' black) | |
225 Font color string | |
226 | |
227 font_weight : string, optional (default='normal') | |
228 Font weight | |
229 | |
230 font_family : string, optional (default='sans-serif') | |
231 Font family | |
232 | |
233 label : string, optional | |
234 Label for graph legend | |
235 | |
236 kwds : optional keywords | |
237 See networkx.draw_networkx_nodes(), networkx.draw_networkx_edges(), and | |
238 networkx.draw_networkx_labels() for a description of optional keywords. | |
239 | |
240 Notes | |
241 ----- | |
242 For directed graphs, arrows are drawn at the head end. Arrows can be | |
243 turned off with keyword arrows=False. | |
244 | |
245 Examples | |
246 -------- | |
247 >>> G = nx.dodecahedral_graph() | |
248 >>> nx.draw(G) | |
249 >>> nx.draw(G, pos=nx.spring_layout(G)) # use spring layout | |
250 | |
251 >>> import matplotlib.pyplot as plt | |
252 >>> limits = plt.axis("off") # turn of axis | |
253 | |
254 Also see the NetworkX drawing examples at | |
255 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
256 | |
257 See Also | |
258 -------- | |
259 draw() | |
260 draw_networkx_nodes() | |
261 draw_networkx_edges() | |
262 draw_networkx_labels() | |
263 draw_networkx_edge_labels() | |
264 """ | |
265 try: | |
266 import matplotlib.pyplot as plt | |
267 except ImportError as e: | |
268 raise ImportError("Matplotlib required for draw()") from e | |
269 except RuntimeError: | |
270 print("Matplotlib unable to open display") | |
271 raise | |
272 | |
273 valid_node_kwds = ( | |
274 "nodelist", | |
275 "node_size", | |
276 "node_color", | |
277 "node_shape", | |
278 "alpha", | |
279 "cmap", | |
280 "vmin", | |
281 "vmax", | |
282 "ax", | |
283 "linewidths", | |
284 "edgecolors", | |
285 "label", | |
286 ) | |
287 | |
288 valid_edge_kwds = ( | |
289 "edgelist", | |
290 "width", | |
291 "edge_color", | |
292 "style", | |
293 "alpha", | |
294 "arrowstyle", | |
295 "arrowsize", | |
296 "edge_cmap", | |
297 "edge_vmin", | |
298 "edge_vmax", | |
299 "ax", | |
300 "label", | |
301 "node_size", | |
302 "nodelist", | |
303 "node_shape", | |
304 "connectionstyle", | |
305 "min_source_margin", | |
306 "min_target_margin", | |
307 ) | |
308 | |
309 valid_label_kwds = ( | |
310 "labels", | |
311 "font_size", | |
312 "font_color", | |
313 "font_family", | |
314 "font_weight", | |
315 "alpha", | |
316 "bbox", | |
317 "ax", | |
318 "horizontalalignment", | |
319 "verticalalignment", | |
320 ) | |
321 | |
322 valid_kwds = valid_node_kwds + valid_edge_kwds + valid_label_kwds | |
323 | |
324 if any([k not in valid_kwds for k in kwds]): | |
325 invalid_args = ", ".join([k for k in kwds if k not in valid_kwds]) | |
326 raise ValueError(f"Received invalid argument(s): {invalid_args}") | |
327 | |
328 node_kwds = {k: v for k, v in kwds.items() if k in valid_node_kwds} | |
329 edge_kwds = {k: v for k, v in kwds.items() if k in valid_edge_kwds} | |
330 label_kwds = {k: v for k, v in kwds.items() if k in valid_label_kwds} | |
331 | |
332 if pos is None: | |
333 pos = nx.drawing.spring_layout(G) # default to spring layout | |
334 | |
335 draw_networkx_nodes(G, pos, **node_kwds) | |
336 draw_networkx_edges(G, pos, arrows=arrows, **edge_kwds) | |
337 if with_labels: | |
338 draw_networkx_labels(G, pos, **label_kwds) | |
339 plt.draw_if_interactive() | |
340 | |
341 | |
342 def draw_networkx_nodes( | |
343 G, | |
344 pos, | |
345 nodelist=None, | |
346 node_size=300, | |
347 node_color="#1f78b4", | |
348 node_shape="o", | |
349 alpha=None, | |
350 cmap=None, | |
351 vmin=None, | |
352 vmax=None, | |
353 ax=None, | |
354 linewidths=None, | |
355 edgecolors=None, | |
356 label=None, | |
357 ): | |
358 """Draw the nodes of the graph G. | |
359 | |
360 This draws only the nodes of the graph G. | |
361 | |
362 Parameters | |
363 ---------- | |
364 G : graph | |
365 A networkx graph | |
366 | |
367 pos : dictionary | |
368 A dictionary with nodes as keys and positions as values. | |
369 Positions should be sequences of length 2. | |
370 | |
371 ax : Matplotlib Axes object, optional | |
372 Draw the graph in the specified Matplotlib axes. | |
373 | |
374 nodelist : list, optional | |
375 Draw only specified nodes (default G.nodes()) | |
376 | |
377 node_size : scalar or array | |
378 Size of nodes (default=300). If an array is specified it must be the | |
379 same length as nodelist. | |
380 | |
381 node_color : color or array of colors (default='#1f78b4') | |
382 Node color. Can be a single color or a sequence of colors with the same | |
383 length as nodelist. Color can be string, or rgb (or rgba) tuple of | |
384 floats from 0-1. If numeric values are specified they will be | |
385 mapped to colors using the cmap and vmin,vmax parameters. See | |
386 matplotlib.scatter for more details. | |
387 | |
388 node_shape : string | |
389 The shape of the node. Specification is as matplotlib.scatter | |
390 marker, one of 'so^>v<dph8' (default='o'). | |
391 | |
392 alpha : float or array of floats | |
393 The node transparency. This can be a single alpha value (default=None), | |
394 in which case it will be applied to all the nodes of color. Otherwise, | |
395 if it is an array, the elements of alpha will be applied to the colors | |
396 in order (cycling through alpha multiple times if necessary). | |
397 | |
398 cmap : Matplotlib colormap | |
399 Colormap for mapping intensities of nodes (default=None) | |
400 | |
401 vmin,vmax : floats | |
402 Minimum and maximum for node colormap scaling (default=None) | |
403 | |
404 linewidths : [None | scalar | sequence] | |
405 Line width of symbol border (default =1.0) | |
406 | |
407 edgecolors : [None | scalar | sequence] | |
408 Colors of node borders (default = node_color) | |
409 | |
410 label : [None| string] | |
411 Label for legend | |
412 | |
413 Returns | |
414 ------- | |
415 matplotlib.collections.PathCollection | |
416 `PathCollection` of the nodes. | |
417 | |
418 Examples | |
419 -------- | |
420 >>> G = nx.dodecahedral_graph() | |
421 >>> nodes = nx.draw_networkx_nodes(G, pos=nx.spring_layout(G)) | |
422 | |
423 Also see the NetworkX drawing examples at | |
424 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
425 | |
426 See Also | |
427 -------- | |
428 draw() | |
429 draw_networkx() | |
430 draw_networkx_edges() | |
431 draw_networkx_labels() | |
432 draw_networkx_edge_labels() | |
433 """ | |
434 from collections.abc import Iterable | |
435 | |
436 try: | |
437 import matplotlib.pyplot as plt | |
438 from matplotlib.collections import PathCollection | |
439 import numpy as np | |
440 except ImportError as e: | |
441 raise ImportError("Matplotlib required for draw()") from e | |
442 except RuntimeError: | |
443 print("Matplotlib unable to open display") | |
444 raise | |
445 | |
446 if ax is None: | |
447 ax = plt.gca() | |
448 | |
449 if nodelist is None: | |
450 nodelist = list(G) | |
451 | |
452 if len(nodelist) == 0: # empty nodelist, no drawing | |
453 return PathCollection(None) | |
454 | |
455 try: | |
456 xy = np.asarray([pos[v] for v in nodelist]) | |
457 except KeyError as e: | |
458 raise nx.NetworkXError(f"Node {e} has no position.") from e | |
459 except ValueError as e: | |
460 raise nx.NetworkXError("Bad value in node positions.") from e | |
461 | |
462 if isinstance(alpha, Iterable): | |
463 node_color = apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax) | |
464 alpha = None | |
465 | |
466 node_collection = ax.scatter( | |
467 xy[:, 0], | |
468 xy[:, 1], | |
469 s=node_size, | |
470 c=node_color, | |
471 marker=node_shape, | |
472 cmap=cmap, | |
473 vmin=vmin, | |
474 vmax=vmax, | |
475 alpha=alpha, | |
476 linewidths=linewidths, | |
477 edgecolors=edgecolors, | |
478 label=label, | |
479 ) | |
480 ax.tick_params( | |
481 axis="both", | |
482 which="both", | |
483 bottom=False, | |
484 left=False, | |
485 labelbottom=False, | |
486 labelleft=False, | |
487 ) | |
488 | |
489 node_collection.set_zorder(2) | |
490 return node_collection | |
491 | |
492 | |
493 def draw_networkx_edges( | |
494 G, | |
495 pos, | |
496 edgelist=None, | |
497 width=1.0, | |
498 edge_color="k", | |
499 style="solid", | |
500 alpha=None, | |
501 arrowstyle="-|>", | |
502 arrowsize=10, | |
503 edge_cmap=None, | |
504 edge_vmin=None, | |
505 edge_vmax=None, | |
506 ax=None, | |
507 arrows=True, | |
508 label=None, | |
509 node_size=300, | |
510 nodelist=None, | |
511 node_shape="o", | |
512 connectionstyle=None, | |
513 min_source_margin=0, | |
514 min_target_margin=0, | |
515 ): | |
516 """Draw the edges of the graph G. | |
517 | |
518 This draws only the edges of the graph G. | |
519 | |
520 Parameters | |
521 ---------- | |
522 G : graph | |
523 A networkx graph | |
524 | |
525 pos : dictionary | |
526 A dictionary with nodes as keys and positions as values. | |
527 Positions should be sequences of length 2. | |
528 | |
529 edgelist : collection of edge tuples | |
530 Draw only specified edges(default=G.edges()) | |
531 | |
532 width : float, or array of floats | |
533 Line width of edges (default=1.0) | |
534 | |
535 edge_color : color or array of colors (default='k') | |
536 Edge color. Can be a single color or a sequence of colors with the same | |
537 length as edgelist. Color can be string, or rgb (or rgba) tuple of | |
538 floats from 0-1. If numeric values are specified they will be | |
539 mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters. | |
540 | |
541 style : string | |
542 Edge line style (default='solid') (solid|dashed|dotted,dashdot) | |
543 | |
544 alpha : float | |
545 The edge transparency (default=None) | |
546 | |
547 edge_ cmap : Matplotlib colormap | |
548 Colormap for mapping intensities of edges (default=None) | |
549 | |
550 edge_vmin,edge_vmax : floats | |
551 Minimum and maximum for edge colormap scaling (default=None) | |
552 | |
553 ax : Matplotlib Axes object, optional | |
554 Draw the graph in the specified Matplotlib axes. | |
555 | |
556 arrows : bool, optional (default=True) | |
557 For directed graphs, if True draw arrowheads. | |
558 Note: Arrows will be the same color as edges. | |
559 | |
560 arrowstyle : str, optional (default='-|>') | |
561 For directed graphs, choose the style of the arrow heads. | |
562 See :py:class: `matplotlib.patches.ArrowStyle` for more | |
563 options. | |
564 | |
565 arrowsize : int, optional (default=10) | |
566 For directed graphs, choose the size of the arrow head head's length and | |
567 width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute | |
568 `mutation_scale` for more info. | |
569 | |
570 connectionstyle : str, optional (default=None) | |
571 Pass the connectionstyle parameter to create curved arc of rounding | |
572 radius rad. For example, connectionstyle='arc3,rad=0.2'. | |
573 See :py:class: `matplotlib.patches.ConnectionStyle` and | |
574 :py:class: `matplotlib.patches.FancyArrowPatch` for more info. | |
575 | |
576 label : [None| string] | |
577 Label for legend | |
578 | |
579 min_source_margin : int, optional (default=0) | |
580 The minimum margin (gap) at the begining of the edge at the source. | |
581 | |
582 min_target_margin : int, optional (default=0) | |
583 The minimum margin (gap) at the end of the edge at the target. | |
584 | |
585 Returns | |
586 ------- | |
587 matplotlib.collection.LineCollection | |
588 `LineCollection` of the edges | |
589 | |
590 list of matplotlib.patches.FancyArrowPatch | |
591 `FancyArrowPatch` instances of the directed edges | |
592 | |
593 Depending whether the drawing includes arrows or not. | |
594 | |
595 Notes | |
596 ----- | |
597 For directed graphs, arrows are drawn at the head end. Arrows can be | |
598 turned off with keyword arrows=False. Be sure to include `node_size` as a | |
599 keyword argument; arrows are drawn considering the size of nodes. | |
600 | |
601 Examples | |
602 -------- | |
603 >>> G = nx.dodecahedral_graph() | |
604 >>> edges = nx.draw_networkx_edges(G, pos=nx.spring_layout(G)) | |
605 | |
606 >>> G = nx.DiGraph() | |
607 >>> G.add_edges_from([(1, 2), (1, 3), (2, 3)]) | |
608 >>> arcs = nx.draw_networkx_edges(G, pos=nx.spring_layout(G)) | |
609 >>> alphas = [0.3, 0.4, 0.5] | |
610 >>> for i, arc in enumerate(arcs): # change alpha values of arcs | |
611 ... arc.set_alpha(alphas[i]) | |
612 | |
613 Also see the NetworkX drawing examples at | |
614 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
615 | |
616 See Also | |
617 -------- | |
618 draw() | |
619 draw_networkx() | |
620 draw_networkx_nodes() | |
621 draw_networkx_labels() | |
622 draw_networkx_edge_labels() | |
623 """ | |
624 try: | |
625 import matplotlib.pyplot as plt | |
626 from matplotlib.colors import colorConverter, Colormap, Normalize | |
627 from matplotlib.collections import LineCollection | |
628 from matplotlib.patches import FancyArrowPatch | |
629 import numpy as np | |
630 except ImportError as e: | |
631 raise ImportError("Matplotlib required for draw()") from e | |
632 except RuntimeError: | |
633 print("Matplotlib unable to open display") | |
634 raise | |
635 | |
636 if ax is None: | |
637 ax = plt.gca() | |
638 | |
639 if edgelist is None: | |
640 edgelist = list(G.edges()) | |
641 | |
642 if len(edgelist) == 0: # no edges! | |
643 if not G.is_directed() or not arrows: | |
644 return LineCollection(None) | |
645 else: | |
646 return [] | |
647 | |
648 if nodelist is None: | |
649 nodelist = list(G.nodes()) | |
650 | |
651 # FancyArrowPatch handles color=None different from LineCollection | |
652 if edge_color is None: | |
653 edge_color = "k" | |
654 | |
655 # set edge positions | |
656 edge_pos = np.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist]) | |
657 | |
658 # Check if edge_color is an array of floats and map to edge_cmap. | |
659 # This is the only case handled differently from matplotlib | |
660 if ( | |
661 np.iterable(edge_color) | |
662 and (len(edge_color) == len(edge_pos)) | |
663 and np.alltrue([isinstance(c, Number) for c in edge_color]) | |
664 ): | |
665 if edge_cmap is not None: | |
666 assert isinstance(edge_cmap, Colormap) | |
667 else: | |
668 edge_cmap = plt.get_cmap() | |
669 if edge_vmin is None: | |
670 edge_vmin = min(edge_color) | |
671 if edge_vmax is None: | |
672 edge_vmax = max(edge_color) | |
673 color_normal = Normalize(vmin=edge_vmin, vmax=edge_vmax) | |
674 edge_color = [edge_cmap(color_normal(e)) for e in edge_color] | |
675 | |
676 if not G.is_directed() or not arrows: | |
677 edge_collection = LineCollection( | |
678 edge_pos, | |
679 colors=edge_color, | |
680 linewidths=width, | |
681 antialiaseds=(1,), | |
682 linestyle=style, | |
683 transOffset=ax.transData, | |
684 alpha=alpha, | |
685 ) | |
686 | |
687 edge_collection.set_cmap(edge_cmap) | |
688 edge_collection.set_clim(edge_vmin, edge_vmax) | |
689 | |
690 edge_collection.set_zorder(1) # edges go behind nodes | |
691 edge_collection.set_label(label) | |
692 ax.add_collection(edge_collection) | |
693 | |
694 return edge_collection | |
695 | |
696 arrow_collection = None | |
697 | |
698 if G.is_directed() and arrows: | |
699 # Note: Waiting for someone to implement arrow to intersection with | |
700 # marker. Meanwhile, this works well for polygons with more than 4 | |
701 # sides and circle. | |
702 | |
703 def to_marker_edge(marker_size, marker): | |
704 if marker in "s^>v<d": # `large` markers need extra space | |
705 return np.sqrt(2 * marker_size) / 2 | |
706 else: | |
707 return np.sqrt(marker_size) / 2 | |
708 | |
709 # Draw arrows with `matplotlib.patches.FancyarrowPatch` | |
710 arrow_collection = [] | |
711 mutation_scale = arrowsize # scale factor of arrow head | |
712 | |
713 # FancyArrowPatch doesn't handle color strings | |
714 arrow_colors = colorConverter.to_rgba_array(edge_color, alpha) | |
715 for i, (src, dst) in enumerate(edge_pos): | |
716 x1, y1 = src | |
717 x2, y2 = dst | |
718 shrink_source = 0 # space from source to tail | |
719 shrink_target = 0 # space from head to target | |
720 if np.iterable(node_size): # many node sizes | |
721 source, target = edgelist[i][:2] | |
722 source_node_size = node_size[nodelist.index(source)] | |
723 target_node_size = node_size[nodelist.index(target)] | |
724 shrink_source = to_marker_edge(source_node_size, node_shape) | |
725 shrink_target = to_marker_edge(target_node_size, node_shape) | |
726 else: | |
727 shrink_source = shrink_target = to_marker_edge(node_size, node_shape) | |
728 | |
729 if shrink_source < min_source_margin: | |
730 shrink_source = min_source_margin | |
731 | |
732 if shrink_target < min_target_margin: | |
733 shrink_target = min_target_margin | |
734 | |
735 if len(arrow_colors) == len(edge_pos): | |
736 arrow_color = arrow_colors[i] | |
737 elif len(arrow_colors) == 1: | |
738 arrow_color = arrow_colors[0] | |
739 else: # Cycle through colors | |
740 arrow_color = arrow_colors[i % len(arrow_colors)] | |
741 | |
742 if np.iterable(width): | |
743 if len(width) == len(edge_pos): | |
744 line_width = width[i] | |
745 else: | |
746 line_width = width[i % len(width)] | |
747 else: | |
748 line_width = width | |
749 | |
750 arrow = FancyArrowPatch( | |
751 (x1, y1), | |
752 (x2, y2), | |
753 arrowstyle=arrowstyle, | |
754 shrinkA=shrink_source, | |
755 shrinkB=shrink_target, | |
756 mutation_scale=mutation_scale, | |
757 color=arrow_color, | |
758 linewidth=line_width, | |
759 connectionstyle=connectionstyle, | |
760 linestyle=style, | |
761 zorder=1, | |
762 ) # arrows go behind nodes | |
763 | |
764 # There seems to be a bug in matplotlib to make collections of | |
765 # FancyArrowPatch instances. Until fixed, the patches are added | |
766 # individually to the axes instance. | |
767 arrow_collection.append(arrow) | |
768 ax.add_patch(arrow) | |
769 | |
770 # update view | |
771 minx = np.amin(np.ravel(edge_pos[:, :, 0])) | |
772 maxx = np.amax(np.ravel(edge_pos[:, :, 0])) | |
773 miny = np.amin(np.ravel(edge_pos[:, :, 1])) | |
774 maxy = np.amax(np.ravel(edge_pos[:, :, 1])) | |
775 | |
776 w = maxx - minx | |
777 h = maxy - miny | |
778 padx, pady = 0.05 * w, 0.05 * h | |
779 corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady) | |
780 ax.update_datalim(corners) | |
781 ax.autoscale_view() | |
782 | |
783 ax.tick_params( | |
784 axis="both", | |
785 which="both", | |
786 bottom=False, | |
787 left=False, | |
788 labelbottom=False, | |
789 labelleft=False, | |
790 ) | |
791 | |
792 return arrow_collection | |
793 | |
794 | |
795 def draw_networkx_labels( | |
796 G, | |
797 pos, | |
798 labels=None, | |
799 font_size=12, | |
800 font_color="k", | |
801 font_family="sans-serif", | |
802 font_weight="normal", | |
803 alpha=None, | |
804 bbox=None, | |
805 horizontalalignment="center", | |
806 verticalalignment="center", | |
807 ax=None, | |
808 ): | |
809 """Draw node labels on the graph G. | |
810 | |
811 Parameters | |
812 ---------- | |
813 G : graph | |
814 A networkx graph | |
815 | |
816 pos : dictionary | |
817 A dictionary with nodes as keys and positions as values. | |
818 Positions should be sequences of length 2. | |
819 | |
820 labels : dictionary, optional (default=None) | |
821 Node labels in a dictionary keyed by node of text labels | |
822 Node-keys in labels should appear as keys in `pos`. | |
823 If needed use: `{n:lab for n,lab in labels.items() if n in pos}` | |
824 | |
825 font_size : int | |
826 Font size for text labels (default=12) | |
827 | |
828 font_color : string | |
829 Font color string (default='k' black) | |
830 | |
831 font_family : string | |
832 Font family (default='sans-serif') | |
833 | |
834 font_weight : string | |
835 Font weight (default='normal') | |
836 | |
837 alpha : float or None | |
838 The text transparency (default=None) | |
839 | |
840 horizontalalignment : {'center', 'right', 'left'} | |
841 Horizontal alignment (default='center') | |
842 | |
843 verticalalignment : {'center', 'top', 'bottom', 'baseline', 'center_baseline'} | |
844 Vertical alignment (default='center') | |
845 | |
846 ax : Matplotlib Axes object, optional | |
847 Draw the graph in the specified Matplotlib axes. | |
848 | |
849 | |
850 Returns | |
851 ------- | |
852 dict | |
853 `dict` of labels keyed on the nodes | |
854 | |
855 Examples | |
856 -------- | |
857 >>> G = nx.dodecahedral_graph() | |
858 >>> labels = nx.draw_networkx_labels(G, pos=nx.spring_layout(G)) | |
859 | |
860 Also see the NetworkX drawing examples at | |
861 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
862 | |
863 See Also | |
864 -------- | |
865 draw() | |
866 draw_networkx() | |
867 draw_networkx_nodes() | |
868 draw_networkx_edges() | |
869 draw_networkx_edge_labels() | |
870 """ | |
871 try: | |
872 import matplotlib.pyplot as plt | |
873 except ImportError as e: | |
874 raise ImportError("Matplotlib required for draw()") from e | |
875 except RuntimeError: | |
876 print("Matplotlib unable to open display") | |
877 raise | |
878 | |
879 if ax is None: | |
880 ax = plt.gca() | |
881 | |
882 if labels is None: | |
883 labels = {n: n for n in G.nodes()} | |
884 | |
885 text_items = {} # there is no text collection so we'll fake one | |
886 for n, label in labels.items(): | |
887 (x, y) = pos[n] | |
888 if not isinstance(label, str): | |
889 label = str(label) # this makes "1" and 1 labeled the same | |
890 t = ax.text( | |
891 x, | |
892 y, | |
893 label, | |
894 size=font_size, | |
895 color=font_color, | |
896 family=font_family, | |
897 weight=font_weight, | |
898 alpha=alpha, | |
899 horizontalalignment=horizontalalignment, | |
900 verticalalignment=verticalalignment, | |
901 transform=ax.transData, | |
902 bbox=bbox, | |
903 clip_on=True, | |
904 ) | |
905 text_items[n] = t | |
906 | |
907 ax.tick_params( | |
908 axis="both", | |
909 which="both", | |
910 bottom=False, | |
911 left=False, | |
912 labelbottom=False, | |
913 labelleft=False, | |
914 ) | |
915 | |
916 return text_items | |
917 | |
918 | |
919 def draw_networkx_edge_labels( | |
920 G, | |
921 pos, | |
922 edge_labels=None, | |
923 label_pos=0.5, | |
924 font_size=10, | |
925 font_color="k", | |
926 font_family="sans-serif", | |
927 font_weight="normal", | |
928 alpha=None, | |
929 bbox=None, | |
930 horizontalalignment="center", | |
931 verticalalignment="center", | |
932 ax=None, | |
933 rotate=True, | |
934 ): | |
935 """Draw edge labels. | |
936 | |
937 Parameters | |
938 ---------- | |
939 G : graph | |
940 A networkx graph | |
941 | |
942 pos : dictionary | |
943 A dictionary with nodes as keys and positions as values. | |
944 Positions should be sequences of length 2. | |
945 | |
946 ax : Matplotlib Axes object, optional | |
947 Draw the graph in the specified Matplotlib axes. | |
948 | |
949 alpha : float or None | |
950 The text transparency (default=None) | |
951 | |
952 edge_labels : dictionary | |
953 Edge labels in a dictionary keyed by edge two-tuple of text | |
954 labels (default=None). Only labels for the keys in the dictionary | |
955 are drawn. | |
956 | |
957 label_pos : float | |
958 Position of edge label along edge (0=head, 0.5=center, 1=tail) | |
959 | |
960 font_size : int | |
961 Font size for text labels (default=12) | |
962 | |
963 font_color : string | |
964 Font color string (default='k' black) | |
965 | |
966 font_weight : string | |
967 Font weight (default='normal') | |
968 | |
969 font_family : string | |
970 Font family (default='sans-serif') | |
971 | |
972 bbox : Matplotlib bbox | |
973 Specify text box shape and colors. | |
974 | |
975 clip_on : bool | |
976 Turn on clipping at axis boundaries (default=True) | |
977 | |
978 horizontalalignment : {'center', 'right', 'left'} | |
979 Horizontal alignment (default='center') | |
980 | |
981 verticalalignment : {'center', 'top', 'bottom', 'baseline', 'center_baseline'} | |
982 Vertical alignment (default='center') | |
983 | |
984 ax : Matplotlib Axes object, optional | |
985 Draw the graph in the specified Matplotlib axes. | |
986 | |
987 Returns | |
988 ------- | |
989 dict | |
990 `dict` of labels keyed on the edges | |
991 | |
992 Examples | |
993 -------- | |
994 >>> G = nx.dodecahedral_graph() | |
995 >>> edge_labels = nx.draw_networkx_edge_labels(G, pos=nx.spring_layout(G)) | |
996 | |
997 Also see the NetworkX drawing examples at | |
998 https://networkx.github.io/documentation/latest/auto_examples/index.html | |
999 | |
1000 See Also | |
1001 -------- | |
1002 draw() | |
1003 draw_networkx() | |
1004 draw_networkx_nodes() | |
1005 draw_networkx_edges() | |
1006 draw_networkx_labels() | |
1007 """ | |
1008 try: | |
1009 import matplotlib.pyplot as plt | |
1010 import numpy as np | |
1011 except ImportError as e: | |
1012 raise ImportError("Matplotlib required for draw()") from e | |
1013 except RuntimeError: | |
1014 print("Matplotlib unable to open display") | |
1015 raise | |
1016 | |
1017 if ax is None: | |
1018 ax = plt.gca() | |
1019 if edge_labels is None: | |
1020 labels = {(u, v): d for u, v, d in G.edges(data=True)} | |
1021 else: | |
1022 labels = edge_labels | |
1023 text_items = {} | |
1024 for (n1, n2), label in labels.items(): | |
1025 (x1, y1) = pos[n1] | |
1026 (x2, y2) = pos[n2] | |
1027 (x, y) = ( | |
1028 x1 * label_pos + x2 * (1.0 - label_pos), | |
1029 y1 * label_pos + y2 * (1.0 - label_pos), | |
1030 ) | |
1031 | |
1032 if rotate: | |
1033 # in degrees | |
1034 angle = np.arctan2(y2 - y1, x2 - x1) / (2.0 * np.pi) * 360 | |
1035 # make label orientation "right-side-up" | |
1036 if angle > 90: | |
1037 angle -= 180 | |
1038 if angle < -90: | |
1039 angle += 180 | |
1040 # transform data coordinate angle to screen coordinate angle | |
1041 xy = np.array((x, y)) | |
1042 trans_angle = ax.transData.transform_angles( | |
1043 np.array((angle,)), xy.reshape((1, 2)) | |
1044 )[0] | |
1045 else: | |
1046 trans_angle = 0.0 | |
1047 # use default box of white with white border | |
1048 if bbox is None: | |
1049 bbox = dict(boxstyle="round", ec=(1.0, 1.0, 1.0), fc=(1.0, 1.0, 1.0)) | |
1050 if not isinstance(label, str): | |
1051 label = str(label) # this makes "1" and 1 labeled the same | |
1052 | |
1053 t = ax.text( | |
1054 x, | |
1055 y, | |
1056 label, | |
1057 size=font_size, | |
1058 color=font_color, | |
1059 family=font_family, | |
1060 weight=font_weight, | |
1061 alpha=alpha, | |
1062 horizontalalignment=horizontalalignment, | |
1063 verticalalignment=verticalalignment, | |
1064 rotation=trans_angle, | |
1065 transform=ax.transData, | |
1066 bbox=bbox, | |
1067 zorder=1, | |
1068 clip_on=True, | |
1069 ) | |
1070 text_items[(n1, n2)] = t | |
1071 | |
1072 ax.tick_params( | |
1073 axis="both", | |
1074 which="both", | |
1075 bottom=False, | |
1076 left=False, | |
1077 labelbottom=False, | |
1078 labelleft=False, | |
1079 ) | |
1080 | |
1081 return text_items | |
1082 | |
1083 | |
1084 def draw_circular(G, **kwargs): | |
1085 """Draw the graph G with a circular layout. | |
1086 | |
1087 Parameters | |
1088 ---------- | |
1089 G : graph | |
1090 A networkx graph | |
1091 | |
1092 kwargs : optional keywords | |
1093 See networkx.draw_networkx() for a description of optional keywords, | |
1094 with the exception of the pos parameter which is not used by this | |
1095 function. | |
1096 """ | |
1097 draw(G, circular_layout(G), **kwargs) | |
1098 | |
1099 | |
1100 def draw_kamada_kawai(G, **kwargs): | |
1101 """Draw the graph G with a Kamada-Kawai force-directed layout. | |
1102 | |
1103 Parameters | |
1104 ---------- | |
1105 G : graph | |
1106 A networkx graph | |
1107 | |
1108 kwargs : optional keywords | |
1109 See networkx.draw_networkx() for a description of optional keywords, | |
1110 with the exception of the pos parameter which is not used by this | |
1111 function. | |
1112 """ | |
1113 draw(G, kamada_kawai_layout(G), **kwargs) | |
1114 | |
1115 | |
1116 def draw_random(G, **kwargs): | |
1117 """Draw the graph G with a random layout. | |
1118 | |
1119 Parameters | |
1120 ---------- | |
1121 G : graph | |
1122 A networkx graph | |
1123 | |
1124 kwargs : optional keywords | |
1125 See networkx.draw_networkx() for a description of optional keywords, | |
1126 with the exception of the pos parameter which is not used by this | |
1127 function. | |
1128 """ | |
1129 draw(G, random_layout(G), **kwargs) | |
1130 | |
1131 | |
1132 def draw_spectral(G, **kwargs): | |
1133 """Draw the graph G with a spectral 2D layout. | |
1134 | |
1135 Using the unnormalized Laplacian, the layout shows possible clusters of | |
1136 nodes which are an approximation of the ratio cut. The positions are the | |
1137 entries of the second and third eigenvectors corresponding to the | |
1138 ascending eigenvalues starting from the second one. | |
1139 | |
1140 Parameters | |
1141 ---------- | |
1142 G : graph | |
1143 A networkx graph | |
1144 | |
1145 kwargs : optional keywords | |
1146 See networkx.draw_networkx() for a description of optional keywords, | |
1147 with the exception of the pos parameter which is not used by this | |
1148 function. | |
1149 """ | |
1150 draw(G, spectral_layout(G), **kwargs) | |
1151 | |
1152 | |
1153 def draw_spring(G, **kwargs): | |
1154 """Draw the graph G with a spring layout. | |
1155 | |
1156 Parameters | |
1157 ---------- | |
1158 G : graph | |
1159 A networkx graph | |
1160 | |
1161 kwargs : optional keywords | |
1162 See networkx.draw_networkx() for a description of optional keywords, | |
1163 with the exception of the pos parameter which is not used by this | |
1164 function. | |
1165 """ | |
1166 draw(G, spring_layout(G), **kwargs) | |
1167 | |
1168 | |
1169 def draw_shell(G, **kwargs): | |
1170 """Draw networkx graph with shell layout. | |
1171 | |
1172 Parameters | |
1173 ---------- | |
1174 G : graph | |
1175 A networkx graph | |
1176 | |
1177 kwargs : optional keywords | |
1178 See networkx.draw_networkx() for a description of optional keywords, | |
1179 with the exception of the pos parameter which is not used by this | |
1180 function. | |
1181 """ | |
1182 nlist = kwargs.get("nlist", None) | |
1183 if nlist is not None: | |
1184 del kwargs["nlist"] | |
1185 draw(G, shell_layout(G, nlist=nlist), **kwargs) | |
1186 | |
1187 | |
1188 def draw_planar(G, **kwargs): | |
1189 """Draw a planar networkx graph with planar layout. | |
1190 | |
1191 Parameters | |
1192 ---------- | |
1193 G : graph | |
1194 A planar networkx graph | |
1195 | |
1196 kwargs : optional keywords | |
1197 See networkx.draw_networkx() for a description of optional keywords, | |
1198 with the exception of the pos parameter which is not used by this | |
1199 function. | |
1200 """ | |
1201 draw(G, planar_layout(G), **kwargs) | |
1202 | |
1203 | |
1204 def apply_alpha(colors, alpha, elem_list, cmap=None, vmin=None, vmax=None): | |
1205 """Apply an alpha (or list of alphas) to the colors provided. | |
1206 | |
1207 Parameters | |
1208 ---------- | |
1209 | |
1210 colors : color string, or array of floats | |
1211 Color of element. Can be a single color format string (default='r'), | |
1212 or a sequence of colors with the same length as nodelist. | |
1213 If numeric values are specified they will be mapped to | |
1214 colors using the cmap and vmin,vmax parameters. See | |
1215 matplotlib.scatter for more details. | |
1216 | |
1217 alpha : float or array of floats | |
1218 Alpha values for elements. This can be a single alpha value, in | |
1219 which case it will be applied to all the elements of color. Otherwise, | |
1220 if it is an array, the elements of alpha will be applied to the colors | |
1221 in order (cycling through alpha multiple times if necessary). | |
1222 | |
1223 elem_list : array of networkx objects | |
1224 The list of elements which are being colored. These could be nodes, | |
1225 edges or labels. | |
1226 | |
1227 cmap : matplotlib colormap | |
1228 Color map for use if colors is a list of floats corresponding to points | |
1229 on a color mapping. | |
1230 | |
1231 vmin, vmax : float | |
1232 Minimum and maximum values for normalizing colors if a color mapping is | |
1233 used. | |
1234 | |
1235 Returns | |
1236 ------- | |
1237 | |
1238 rgba_colors : numpy ndarray | |
1239 Array containing RGBA format values for each of the node colours. | |
1240 | |
1241 """ | |
1242 from itertools import islice, cycle | |
1243 | |
1244 try: | |
1245 import numpy as np | |
1246 from matplotlib.colors import colorConverter | |
1247 import matplotlib.cm as cm | |
1248 except ImportError as e: | |
1249 raise ImportError("Matplotlib required for draw()") from e | |
1250 | |
1251 # If we have been provided with a list of numbers as long as elem_list, | |
1252 # apply the color mapping. | |
1253 if len(colors) == len(elem_list) and isinstance(colors[0], Number): | |
1254 mapper = cm.ScalarMappable(cmap=cmap) | |
1255 mapper.set_clim(vmin, vmax) | |
1256 rgba_colors = mapper.to_rgba(colors) | |
1257 # Otherwise, convert colors to matplotlib's RGB using the colorConverter | |
1258 # object. These are converted to numpy ndarrays to be consistent with the | |
1259 # to_rgba method of ScalarMappable. | |
1260 else: | |
1261 try: | |
1262 rgba_colors = np.array([colorConverter.to_rgba(colors)]) | |
1263 except ValueError: | |
1264 rgba_colors = np.array([colorConverter.to_rgba(color) for color in colors]) | |
1265 # Set the final column of the rgba_colors to have the relevant alpha values | |
1266 try: | |
1267 # If alpha is longer than the number of colors, resize to the number of | |
1268 # elements. Also, if rgba_colors.size (the number of elements of | |
1269 # rgba_colors) is the same as the number of elements, resize the array, | |
1270 # to avoid it being interpreted as a colormap by scatter() | |
1271 if len(alpha) > len(rgba_colors) or rgba_colors.size == len(elem_list): | |
1272 rgba_colors = np.resize(rgba_colors, (len(elem_list), 4)) | |
1273 rgba_colors[1:, 0] = rgba_colors[0, 0] | |
1274 rgba_colors[1:, 1] = rgba_colors[0, 1] | |
1275 rgba_colors[1:, 2] = rgba_colors[0, 2] | |
1276 rgba_colors[:, 3] = list(islice(cycle(alpha), len(rgba_colors))) | |
1277 except TypeError: | |
1278 rgba_colors[:, -1] = alpha | |
1279 return rgba_colors |