Mercurial > repos > guerler > springsuite
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/planemo/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py Fri Jul 31 00:32:28 2020 -0400 @@ -0,0 +1,1186 @@ +# Copyright (C) 2004-2019 by +# Aric Hagberg <hagberg@lanl.gov> +# Dan Schult <dschult@colgate.edu> +# Pieter Swart <swart@lanl.gov> +# All rights reserved. +# BSD license. +# +# Author: Aric Hagberg (hagberg@lanl.gov) +""" +********** +Matplotlib +********** + +Draw networks with matplotlib. + +See Also +-------- + +matplotlib: http://matplotlib.org/ + +pygraphviz: http://pygraphviz.github.io/ + +""" +from numbers import Number +import networkx as nx +from networkx.utils import is_string_like +from networkx.drawing.layout import shell_layout, \ + circular_layout, kamada_kawai_layout, spectral_layout, \ + spring_layout, random_layout, planar_layout + +__all__ = ['draw', + 'draw_networkx', + 'draw_networkx_nodes', + 'draw_networkx_edges', + 'draw_networkx_labels', + 'draw_networkx_edge_labels', + 'draw_circular', + 'draw_kamada_kawai', + 'draw_random', + 'draw_spectral', + 'draw_spring', + 'draw_planar', + 'draw_shell'] + + +def draw(G, pos=None, ax=None, **kwds): + """Draw the graph G with Matplotlib. + + Draw the graph as a simple representation with no node + labels or edge labels and using the full Matplotlib figure area + and no axis labels by default. See draw_networkx() for more + full-featured drawing that allows title, axis labels etc. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary, optional + A dictionary with nodes as keys and positions as values. + If not specified a spring layout positioning will be computed. + See :py:mod:`networkx.drawing.layout` for functions that + compute node positions. + + ax : Matplotlib Axes object, optional + Draw the graph in specified Matplotlib axes. + + kwds : optional keywords + See networkx.draw_networkx() for a description of optional keywords. + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> nx.draw(G) + >>> nx.draw(G, pos=nx.spring_layout(G)) # use spring layout + + See Also + -------- + draw_networkx() + draw_networkx_nodes() + draw_networkx_edges() + draw_networkx_labels() + draw_networkx_edge_labels() + + Notes + ----- + This function has the same name as pylab.draw and pyplot.draw + so beware when using `from networkx import *` + + since you might overwrite the pylab.draw function. + + With pyplot use + + >>> import matplotlib.pyplot as plt + >>> import networkx as nx + >>> G = nx.dodecahedral_graph() + >>> nx.draw(G) # networkx draw() + >>> plt.draw() # pyplot draw() + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + """ + try: + import matplotlib.pyplot as plt + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if ax is None: + cf = plt.gcf() + else: + cf = ax.get_figure() + cf.set_facecolor('w') + if ax is None: + if cf._axstack() is None: + ax = cf.add_axes((0, 0, 1, 1)) + else: + ax = cf.gca() + + if 'with_labels' not in kwds: + kwds['with_labels'] = 'labels' in kwds + + draw_networkx(G, pos=pos, ax=ax, **kwds) + ax.set_axis_off() + plt.draw_if_interactive() + return + + +def draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds): + """Draw the graph G using Matplotlib. + + Draw the graph with Matplotlib with options for node positions, + labeling, titles, and many other drawing features. + See draw() for simple drawing without labels or axes. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary, optional + A dictionary with nodes as keys and positions as values. + If not specified a spring layout positioning will be computed. + See :py:mod:`networkx.drawing.layout` for functions that + compute node positions. + + arrows : bool, optional (default=True) + For directed graphs, if True draw arrowheads. + Note: Arrows will be the same color as edges. + + arrowstyle : str, optional (default='-|>') + For directed graphs, choose the style of the arrowsheads. + See :py:class: `matplotlib.patches.ArrowStyle` for more + options. + + arrowsize : int, optional (default=10) + For directed graphs, choose the size of the arrow head head's length and + width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute + `mutation_scale` for more info. + + with_labels : bool, optional (default=True) + Set to True to draw labels on the nodes. + + ax : Matplotlib Axes object, optional + Draw the graph in the specified Matplotlib axes. + + nodelist : list, optional (default G.nodes()) + Draw only specified nodes + + edgelist : list, optional (default=G.edges()) + Draw only specified edges + + node_size : scalar or array, optional (default=300) + Size of nodes. If an array is specified it must be the + same length as nodelist. + + node_color : color or array of colors (default='#1f78b4') + Node color. Can be a single color or a sequence of colors with the same + length as nodelist. Color can be string, or rgb (or rgba) tuple of + floats from 0-1. If numeric values are specified they will be + mapped to colors using the cmap and vmin,vmax parameters. See + matplotlib.scatter for more details. + + node_shape : string, optional (default='o') + The shape of the node. Specification is as matplotlib.scatter + marker, one of 'so^>v<dph8'. + + alpha : float, optional (default=None) + The node and edge transparency + + cmap : Matplotlib colormap, optional (default=None) + Colormap for mapping intensities of nodes + + vmin,vmax : float, optional (default=None) + Minimum and maximum for node colormap scaling + + linewidths : [None | scalar | sequence] + Line width of symbol border (default =1.0) + + width : float, optional (default=1.0) + Line width of edges + + edge_color : color or array of colors (default='k') + Edge color. Can be a single color or a sequence of colors with the same + length as edgelist. Color can be string, or rgb (or rgba) tuple of + floats from 0-1. If numeric values are specified they will be + mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters. + + edge_cmap : Matplotlib colormap, optional (default=None) + Colormap for mapping intensities of edges + + edge_vmin,edge_vmax : floats, optional (default=None) + Minimum and maximum for edge colormap scaling + + style : string, optional (default='solid') + Edge line style (solid|dashed|dotted,dashdot) + + labels : dictionary, optional (default=None) + Node labels in a dictionary keyed by node of text labels + + font_size : int, optional (default=12) + Font size for text labels + + font_color : string, optional (default='k' black) + Font color string + + font_weight : string, optional (default='normal') + Font weight + + font_family : string, optional (default='sans-serif') + Font family + + label : string, optional + Label for graph legend + + Notes + ----- + For directed graphs, arrows are drawn at the head end. Arrows can be + turned off with keyword arrows=False. + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> nx.draw(G) + >>> nx.draw(G, pos=nx.spring_layout(G)) # use spring layout + + >>> import matplotlib.pyplot as plt + >>> limits = plt.axis('off') # turn of axis + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + + See Also + -------- + draw() + draw_networkx_nodes() + draw_networkx_edges() + draw_networkx_labels() + draw_networkx_edge_labels() + """ + try: + import matplotlib.pyplot as plt + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if pos is None: + pos = nx.drawing.spring_layout(G) # default to spring layout + + node_collection = draw_networkx_nodes(G, pos, **kwds) + edge_collection = draw_networkx_edges(G, pos, arrows=arrows, **kwds) + if with_labels: + draw_networkx_labels(G, pos, **kwds) + plt.draw_if_interactive() + + +def draw_networkx_nodes(G, pos, + nodelist=None, + node_size=300, + node_color='#1f78b4', + node_shape='o', + alpha=None, + cmap=None, + vmin=None, + vmax=None, + ax=None, + linewidths=None, + edgecolors=None, + label=None, + **kwds): + """Draw the nodes of the graph G. + + This draws only the nodes of the graph G. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary + A dictionary with nodes as keys and positions as values. + Positions should be sequences of length 2. + + ax : Matplotlib Axes object, optional + Draw the graph in the specified Matplotlib axes. + + nodelist : list, optional + Draw only specified nodes (default G.nodes()) + + node_size : scalar or array + Size of nodes (default=300). If an array is specified it must be the + same length as nodelist. + + node_color : color or array of colors (default='#1f78b4') + Node color. Can be a single color or a sequence of colors with the same + length as nodelist. Color can be string, or rgb (or rgba) tuple of + floats from 0-1. If numeric values are specified they will be + mapped to colors using the cmap and vmin,vmax parameters. See + matplotlib.scatter for more details. + + node_shape : string + The shape of the node. Specification is as matplotlib.scatter + marker, one of 'so^>v<dph8' (default='o'). + + alpha : float or array of floats + The node transparency. This can be a single alpha value (default=None), + in which case it will be applied to all the nodes of color. Otherwise, + if it is an array, the elements of alpha will be applied to the colors + in order (cycling through alpha multiple times if necessary). + + cmap : Matplotlib colormap + Colormap for mapping intensities of nodes (default=None) + + vmin,vmax : floats + Minimum and maximum for node colormap scaling (default=None) + + linewidths : [None | scalar | sequence] + Line width of symbol border (default =1.0) + + edgecolors : [None | scalar | sequence] + Colors of node borders (default = node_color) + + label : [None| string] + Label for legend + + min_source_margin : int, optional (default=0) + The minimum margin (gap) at the begining of the edge at the source. + + min_target_margin : int, optional (default=0) + The minimum margin (gap) at the end of the edge at the target. + + Returns + ------- + matplotlib.collections.PathCollection + `PathCollection` of the nodes. + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> nodes = nx.draw_networkx_nodes(G, pos=nx.spring_layout(G)) + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + + See Also + -------- + draw() + draw_networkx() + draw_networkx_edges() + draw_networkx_labels() + draw_networkx_edge_labels() + """ + from collections.abc import Iterable + try: + import matplotlib.pyplot as plt + import numpy as np + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if ax is None: + ax = plt.gca() + + if nodelist is None: + nodelist = list(G) + + if len(nodelist) == 0: # empty nodelist, no drawing + return + + try: + xy = np.asarray([pos[v] for v in nodelist]) + except KeyError as e: + raise nx.NetworkXError('Node %s has no position.' % e) + except ValueError: + raise nx.NetworkXError('Bad value in node positions.') + + if isinstance(alpha, Iterable): + node_color = apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax) + alpha = None + + node_collection = ax.scatter(xy[:, 0], xy[:, 1], + s=node_size, + c=node_color, + marker=node_shape, + cmap=cmap, + vmin=vmin, + vmax=vmax, + alpha=alpha, + linewidths=linewidths, + edgecolors=edgecolors, + label=label) + ax.tick_params( + axis='both', + which='both', + bottom=False, + left=False, + labelbottom=False, + labelleft=False) + + node_collection.set_zorder(2) + return node_collection + + +def draw_networkx_edges(G, pos, + edgelist=None, + width=1.0, + edge_color='k', + style='solid', + alpha=None, + arrowstyle='-|>', + arrowsize=10, + edge_cmap=None, + edge_vmin=None, + edge_vmax=None, + ax=None, + arrows=True, + label=None, + node_size=300, + nodelist=None, + node_shape="o", + connectionstyle=None, + min_source_margin=0, + min_target_margin=0, + **kwds): + """Draw the edges of the graph G. + + This draws only the edges of the graph G. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary + A dictionary with nodes as keys and positions as values. + Positions should be sequences of length 2. + + edgelist : collection of edge tuples + Draw only specified edges(default=G.edges()) + + width : float, or array of floats + Line width of edges (default=1.0) + + edge_color : color or array of colors (default='k') + Edge color. Can be a single color or a sequence of colors with the same + length as edgelist. Color can be string, or rgb (or rgba) tuple of + floats from 0-1. If numeric values are specified they will be + mapped to colors using the edge_cmap and edge_vmin,edge_vmax parameters. + + style : string + Edge line style (default='solid') (solid|dashed|dotted,dashdot) + + alpha : float + The edge transparency (default=None) + + edge_ cmap : Matplotlib colormap + Colormap for mapping intensities of edges (default=None) + + edge_vmin,edge_vmax : floats + Minimum and maximum for edge colormap scaling (default=None) + + ax : Matplotlib Axes object, optional + Draw the graph in the specified Matplotlib axes. + + arrows : bool, optional (default=True) + For directed graphs, if True draw arrowheads. + Note: Arrows will be the same color as edges. + + arrowstyle : str, optional (default='-|>') + For directed graphs, choose the style of the arrow heads. + See :py:class: `matplotlib.patches.ArrowStyle` for more + options. + + arrowsize : int, optional (default=10) + For directed graphs, choose the size of the arrow head head's length and + width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute + `mutation_scale` for more info. + + connectionstyle : str, optional (default=None) + Pass the connectionstyle parameter to create curved arc of rounding + radius rad. For example, connectionstyle='arc3,rad=0.2'. + See :py:class: `matplotlib.patches.ConnectionStyle` and + :py:class: `matplotlib.patches.FancyArrowPatch` for more info. + + label : [None| string] + Label for legend + + min_source_margin : int, optional (default=0) + The minimum margin (gap) at the begining of the edge at the source. + + min_target_margin : int, optional (default=0) + The minimum margin (gap) at the end of the edge at the target. + + Returns + ------- + matplotlib.collection.LineCollection + `LineCollection` of the edges + + list of matplotlib.patches.FancyArrowPatch + `FancyArrowPatch` instances of the directed edges + + Depending whether the drawing includes arrows or not. + + Notes + ----- + For directed graphs, arrows are drawn at the head end. Arrows can be + turned off with keyword arrows=False. Be sure to include `node_size` as a + keyword argument; arrows are drawn considering the size of nodes. + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> edges = nx.draw_networkx_edges(G, pos=nx.spring_layout(G)) + + >>> G = nx.DiGraph() + >>> G.add_edges_from([(1, 2), (1, 3), (2, 3)]) + >>> arcs = nx.draw_networkx_edges(G, pos=nx.spring_layout(G)) + >>> alphas = [0.3, 0.4, 0.5] + >>> for i, arc in enumerate(arcs): # change alpha values of arcs + ... arc.set_alpha(alphas[i]) + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + + See Also + -------- + draw() + draw_networkx() + draw_networkx_nodes() + draw_networkx_labels() + draw_networkx_edge_labels() + """ + try: + import matplotlib + import matplotlib.pyplot as plt + from matplotlib.colors import colorConverter, Colormap, Normalize + from matplotlib.collections import LineCollection + from matplotlib.patches import FancyArrowPatch + import numpy as np + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if ax is None: + ax = plt.gca() + + if edgelist is None: + edgelist = list(G.edges()) + + if not edgelist or len(edgelist) == 0: # no edges! + return None + + if nodelist is None: + nodelist = list(G.nodes()) + + # FancyArrowPatch handles color=None different from LineCollection + if edge_color is None: + edge_color = 'k' + + # set edge positions + edge_pos = np.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist]) + + # Check if edge_color is an array of floats and map to edge_cmap. + # This is the only case handled differently from matplotlib + if np.iterable(edge_color) and (len(edge_color) == len(edge_pos)) \ + and np.alltrue([isinstance(c, Number) for c in edge_color]): + if edge_cmap is not None: + assert(isinstance(edge_cmap, Colormap)) + else: + edge_cmap = plt.get_cmap() + if edge_vmin is None: + edge_vmin = min(edge_color) + if edge_vmax is None: + edge_vmax = max(edge_color) + color_normal = Normalize(vmin=edge_vmin, vmax=edge_vmax) + edge_color = [edge_cmap(color_normal(e)) for e in edge_color] + + if (not G.is_directed() or not arrows): + edge_collection = LineCollection(edge_pos, + colors=edge_color, + linewidths=width, + antialiaseds=(1,), + linestyle=style, + transOffset=ax.transData, + alpha=alpha + ) + + edge_collection.set_zorder(1) # edges go behind nodes + edge_collection.set_label(label) + ax.add_collection(edge_collection) + + return edge_collection + + arrow_collection = None + + if G.is_directed() and arrows: + # Note: Waiting for someone to implement arrow to intersection with + # marker. Meanwhile, this works well for polygons with more than 4 + # sides and circle. + + def to_marker_edge(marker_size, marker): + if marker in "s^>v<d": # `large` markers need extra space + return np.sqrt(2 * marker_size) / 2 + else: + return np.sqrt(marker_size) / 2 + + # Draw arrows with `matplotlib.patches.FancyarrowPatch` + arrow_collection = [] + mutation_scale = arrowsize # scale factor of arrow head + + # FancyArrowPatch doesn't handle color strings + arrow_colors = colorConverter.to_rgba_array(edge_color, alpha) + for i, (src, dst) in enumerate(edge_pos): + x1, y1 = src + x2, y2 = dst + shrink_source = 0 # space from source to tail + shrink_target = 0 # space from head to target + if np.iterable(node_size): # many node sizes + src_node, dst_node = edgelist[i][:2] + index_node = nodelist.index(dst_node) + marker_size = node_size[index_node] + shrink_target = to_marker_edge(marker_size, node_shape) + else: + shrink_target = to_marker_edge(node_size, node_shape) + + if shrink_source < min_source_margin: + shrink_source = min_source_margin + + if shrink_target < min_target_margin: + shrink_target = min_target_margin + + if len(arrow_colors) == len(edge_pos): + arrow_color = arrow_colors[i] + elif len(arrow_colors) == 1: + arrow_color = arrow_colors[0] + else: # Cycle through colors + arrow_color = arrow_colors[i % len(arrow_colors)] + + if np.iterable(width): + if len(width) == len(edge_pos): + line_width = width[i] + else: + line_width = width[i % len(width)] + else: + line_width = width + + arrow = FancyArrowPatch((x1, y1), (x2, y2), + arrowstyle=arrowstyle, + shrinkA=shrink_source, + shrinkB=shrink_target, + mutation_scale=mutation_scale, + color=arrow_color, + linewidth=line_width, + connectionstyle=connectionstyle, + zorder=1) # arrows go behind nodes + + # There seems to be a bug in matplotlib to make collections of + # FancyArrowPatch instances. Until fixed, the patches are added + # individually to the axes instance. + arrow_collection.append(arrow) + ax.add_patch(arrow) + + # update view + minx = np.amin(np.ravel(edge_pos[:, :, 0])) + maxx = np.amax(np.ravel(edge_pos[:, :, 0])) + miny = np.amin(np.ravel(edge_pos[:, :, 1])) + maxy = np.amax(np.ravel(edge_pos[:, :, 1])) + + w = maxx - minx + h = maxy - miny + padx, pady = 0.05 * w, 0.05 * h + corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady) + ax.update_datalim(corners) + ax.autoscale_view() + + ax.tick_params( + axis='both', + which='both', + bottom=False, + left=False, + labelbottom=False, + labelleft=False) + + return arrow_collection + + +def draw_networkx_labels(G, pos, + labels=None, + font_size=12, + font_color='k', + font_family='sans-serif', + font_weight='normal', + alpha=None, + bbox=None, + ax=None, + **kwds): + """Draw node labels on the graph G. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary + A dictionary with nodes as keys and positions as values. + Positions should be sequences of length 2. + + labels : dictionary, optional (default=None) + Node labels in a dictionary keyed by node of text labels + Node-keys in labels should appear as keys in `pos`. + If needed use: `{n:lab for n,lab in labels.items() if n in pos}` + + font_size : int + Font size for text labels (default=12) + + font_color : string + Font color string (default='k' black) + + font_family : string + Font family (default='sans-serif') + + font_weight : string + Font weight (default='normal') + + alpha : float or None + The text transparency (default=None) + + ax : Matplotlib Axes object, optional + Draw the graph in the specified Matplotlib axes. + + Returns + ------- + dict + `dict` of labels keyed on the nodes + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> labels = nx.draw_networkx_labels(G, pos=nx.spring_layout(G)) + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + + See Also + -------- + draw() + draw_networkx() + draw_networkx_nodes() + draw_networkx_edges() + draw_networkx_edge_labels() + """ + try: + import matplotlib.pyplot as plt + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if ax is None: + ax = plt.gca() + + if labels is None: + labels = dict((n, n) for n in G.nodes()) + + # set optional alignment + horizontalalignment = kwds.get('horizontalalignment', 'center') + verticalalignment = kwds.get('verticalalignment', 'center') + + text_items = {} # there is no text collection so we'll fake one + for n, label in labels.items(): + (x, y) = pos[n] + if not is_string_like(label): + label = str(label) # this makes "1" and 1 labeled the same + t = ax.text(x, y, + label, + size=font_size, + color=font_color, + family=font_family, + weight=font_weight, + alpha=alpha, + horizontalalignment=horizontalalignment, + verticalalignment=verticalalignment, + transform=ax.transData, + bbox=bbox, + clip_on=True, + ) + text_items[n] = t + + ax.tick_params( + axis='both', + which='both', + bottom=False, + left=False, + labelbottom=False, + labelleft=False) + + return text_items + + +def draw_networkx_edge_labels(G, pos, + edge_labels=None, + label_pos=0.5, + font_size=10, + font_color='k', + font_family='sans-serif', + font_weight='normal', + alpha=None, + bbox=None, + ax=None, + rotate=True, + **kwds): + """Draw edge labels. + + Parameters + ---------- + G : graph + A networkx graph + + pos : dictionary + A dictionary with nodes as keys and positions as values. + Positions should be sequences of length 2. + + ax : Matplotlib Axes object, optional + Draw the graph in the specified Matplotlib axes. + + alpha : float or None + The text transparency (default=None) + + edge_labels : dictionary + Edge labels in a dictionary keyed by edge two-tuple of text + labels (default=None). Only labels for the keys in the dictionary + are drawn. + + label_pos : float + Position of edge label along edge (0=head, 0.5=center, 1=tail) + + font_size : int + Font size for text labels (default=12) + + font_color : string + Font color string (default='k' black) + + font_weight : string + Font weight (default='normal') + + font_family : string + Font family (default='sans-serif') + + bbox : Matplotlib bbox + Specify text box shape and colors. + + clip_on : bool + Turn on clipping at axis boundaries (default=True) + + Returns + ------- + dict + `dict` of labels keyed on the edges + + Examples + -------- + >>> G = nx.dodecahedral_graph() + >>> edge_labels = nx.draw_networkx_edge_labels(G, pos=nx.spring_layout(G)) + + Also see the NetworkX drawing examples at + https://networkx.github.io/documentation/latest/auto_examples/index.html + + See Also + -------- + draw() + draw_networkx() + draw_networkx_nodes() + draw_networkx_edges() + draw_networkx_labels() + """ + try: + import matplotlib.pyplot as plt + import numpy as np + except ImportError: + raise ImportError("Matplotlib required for draw()") + except RuntimeError: + print("Matplotlib unable to open display") + raise + + if ax is None: + ax = plt.gca() + if edge_labels is None: + labels = {(u, v): d for u, v, d in G.edges(data=True)} + else: + labels = edge_labels + text_items = {} + for (n1, n2), label in labels.items(): + (x1, y1) = pos[n1] + (x2, y2) = pos[n2] + (x, y) = (x1 * label_pos + x2 * (1.0 - label_pos), + y1 * label_pos + y2 * (1.0 - label_pos)) + + if rotate: + # in degrees + angle = np.arctan2(y2 - y1, x2 - x1) / (2.0 * np.pi) * 360 + # make label orientation "right-side-up" + if angle > 90: + angle -= 180 + if angle < - 90: + angle += 180 + # transform data coordinate angle to screen coordinate angle + xy = np.array((x, y)) + trans_angle = ax.transData.transform_angles(np.array((angle,)), + xy.reshape((1, 2)))[0] + else: + trans_angle = 0.0 + # use default box of white with white border + if bbox is None: + bbox = dict(boxstyle='round', + ec=(1.0, 1.0, 1.0), + fc=(1.0, 1.0, 1.0), + ) + if not is_string_like(label): + label = str(label) # this makes "1" and 1 labeled the same + + # set optional alignment + horizontalalignment = kwds.get('horizontalalignment', 'center') + verticalalignment = kwds.get('verticalalignment', 'center') + + t = ax.text(x, y, + label, + size=font_size, + color=font_color, + family=font_family, + weight=font_weight, + alpha=alpha, + horizontalalignment=horizontalalignment, + verticalalignment=verticalalignment, + rotation=trans_angle, + transform=ax.transData, + bbox=bbox, + zorder=1, + clip_on=True, + ) + text_items[(n1, n2)] = t + + ax.tick_params( + axis='both', + which='both', + bottom=False, + left=False, + labelbottom=False, + labelleft=False) + + return text_items + + +def draw_circular(G, **kwargs): + """Draw the graph G with a circular layout. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, circular_layout(G), **kwargs) + + +def draw_kamada_kawai(G, **kwargs): + """Draw the graph G with a Kamada-Kawai force-directed layout. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, kamada_kawai_layout(G), **kwargs) + + +def draw_random(G, **kwargs): + """Draw the graph G with a random layout. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, random_layout(G), **kwargs) + + +def draw_spectral(G, **kwargs): + """Draw the graph G with a spectral 2D layout. + + Using the unnormalized Laplacion, the layout shows possible clusters of + nodes which are an approximation of the ratio cut. The positions are the + entries of the second and third eigenvectors corresponding to the + ascending eigenvalues starting from the second one. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, spectral_layout(G), **kwargs) + + +def draw_spring(G, **kwargs): + """Draw the graph G with a spring layout. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, spring_layout(G), **kwargs) + + +def draw_shell(G, **kwargs): + """Draw networkx graph with shell layout. + + Parameters + ---------- + G : graph + A networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + nlist = kwargs.get('nlist', None) + if nlist is not None: + del(kwargs['nlist']) + draw(G, shell_layout(G, nlist=nlist), **kwargs) + + +def draw_planar(G, **kwargs): + """Draw a planar networkx graph with planar layout. + + Parameters + ---------- + G : graph + A planar networkx graph + + kwargs : optional keywords + See networkx.draw_networkx() for a description of optional keywords, + with the exception of the pos parameter which is not used by this + function. + """ + draw(G, planar_layout(G), **kwargs) + + +def apply_alpha(colors, alpha, elem_list, cmap=None, vmin=None, vmax=None): + """Apply an alpha (or list of alphas) to the colors provided. + + Parameters + ---------- + + colors : color string, or array of floats + Color of element. Can be a single color format string (default='r'), + or a sequence of colors with the same length as nodelist. + If numeric values are specified they will be mapped to + colors using the cmap and vmin,vmax parameters. See + matplotlib.scatter for more details. + + alpha : float or array of floats + Alpha values for elements. This can be a single alpha value, in + which case it will be applied to all the elements of color. Otherwise, + if it is an array, the elements of alpha will be applied to the colors + in order (cycling through alpha multiple times if necessary). + + elem_list : array of networkx objects + The list of elements which are being colored. These could be nodes, + edges or labels. + + cmap : matplotlib colormap + Color map for use if colors is a list of floats corresponding to points + on a color mapping. + + vmin, vmax : float + Minimum and maximum values for normalizing colors if a color mapping is + used. + + Returns + ------- + + rgba_colors : numpy ndarray + Array containing RGBA format values for each of the node colours. + + """ + from itertools import islice, cycle + + try: + import numpy as np + from matplotlib.colors import colorConverter + import matplotlib.cm as cm + except ImportError: + raise ImportError("Matplotlib required for draw()") + + # If we have been provided with a list of numbers as long as elem_list, + # apply the color mapping. + if len(colors) == len(elem_list) and isinstance(colors[0], Number): + mapper = cm.ScalarMappable(cmap=cmap) + mapper.set_clim(vmin, vmax) + rgba_colors = mapper.to_rgba(colors) + # Otherwise, convert colors to matplotlib's RGB using the colorConverter + # object. These are converted to numpy ndarrays to be consistent with the + # to_rgba method of ScalarMappable. + else: + try: + rgba_colors = np.array([colorConverter.to_rgba(colors)]) + except ValueError: + rgba_colors = np.array([colorConverter.to_rgba(color) + for color in colors]) + # Set the final column of the rgba_colors to have the relevant alpha values + try: + # If alpha is longer than the number of colors, resize to the number of + # elements. Also, if rgba_colors.size (the number of elements of + # rgba_colors) is the same as the number of elements, resize the array, + # to avoid it being interpreted as a colormap by scatter() + if len(alpha) > len(rgba_colors) or rgba_colors.size == len(elem_list): + rgba_colors = np.resize(rgba_colors, (len(elem_list), 4)) + rgba_colors[1:, 0] = rgba_colors[0, 0] + rgba_colors[1:, 1] = rgba_colors[0, 1] + rgba_colors[1:, 2] = rgba_colors[0, 2] + rgba_colors[:, 3] = list(islice(cycle(alpha), len(rgba_colors))) + except TypeError: + rgba_colors[:, -1] = alpha + return rgba_colors + + +# fixture for pytest +def setup_module(module): + import pytest + mpl = pytest.importorskip('matplotlib') + mpl.use('PS', warn=False) + plt = pytest.importorskip('matplotlib.pyplot')