comparison planemo/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py @ 1:56ad4e20f292 draft

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