Source code for dynamicalab.drawing.draw

import numpy as np
import matplotlib.patches as mpatches
import networkx as nx
from matplotlib.patches import FancyArrowPatch as ArrowPath
from matplotlib.font_manager import FontProperties



[docs]def draw_curved_edges(edges, pos, ax, mu=0.05, edge_color="black", edge_width=1.0, alpha=1.0, arrow_scale=20.0, loopsize=0): """This function plots the edges of a graph with a certain curvature. It can also plot arrows for direction. For self-loop, it is possible to plot an edge that does a circle passing through the node. The size of the circle is controlled by the parameter ``loopsize``. **Parameters** edges : list A list of edges in the tuple format of node ids, ``(nodeA, nodeB)``. pos : dict A dictionary of nodes position. ax : Matplotlib Axes object Draw the edges in the specified Matplotlib axes. mu : float : (default=0.05) Level of curvature. Should always be positive. If zero, then edges are straight. edge_color : str or list : (default="black") If a list, then each entry is the color of the edge when iterated through edges. If a string, then each edge will have the same color. alpha : float : (default=1) Edges opacity. arrow_scale : float : (default=20) Control the size of the arrows. If equal to zero, then the arrows are invisible. loopsize : float : (default=0) If ``edges`` contains self-loops, i.e. ``edge==(nodeA, nodeA)``, then it draw a self-loop which is composed of a simple circle. The radius of the circle is controlled by ``loopsize`` **Example** .. code:: python import networkx as nx import dynamicalab.drawing as draw import matplotlib.pyplot as plt G = nx.erdos_renyi_graph(20,0.1) pos = nx.spring_layout(G) edges = G.edges() fig = plt.figure() ax = plt.gca() draw.draw_curved_edges(edges, pos, ax, mu=5) plt.show() .. seealso:: draw_networks """ for v,edge in enumerate(edges): x1,y1 = pos[edge[0]] x2,y2 = pos[edge[1]] #If self loop if edge[0]==edge[1]: dv = 0.0 theta = np.linspace(0.0,2.0*np.pi, 100) X = np.cos(theta)*loopsize+x1-loopsize Y = np.sin(theta)*loopsize+y1 else: dv = mu if x1>x2: x1,y1 = pos[edge[1]] x2,y2 = pos[edge[0]] dv = -mu dx = x2 dy = y2 # Center to origin x1 -= dx x2 -= dx y1 -= dy y2 -= dy r = ((y2-y1)**2.0 + (x2-x1)**2.0)**(0.5) theta = np.arctan2(y1, x1) c, s = np.cos(theta), np.sin(theta) R = np.matrix('{} {}; {} {}'.format(c, -s, s, c)) # Rotate x1 = x2 - r y1 = y2 # Find parabola h = (x2+x1)/2.0 k = y2+dv*r a = (y2-k)/((x2-h)**2.0) X = np.linspace(x1,x2,100) Y = a*(X-h)**2.0+k # Rotate the parabola and translate theta = np.pi+theta c, s = np.cos(theta), np.sin(theta) R = np.matrix('{} {}; {} {}'.format(c, -s, s, c)) for u in range(len(X)): C1 = np.array([X[u], Y[u]]) C1 = np.dot(R, C1) X[u], Y[u] = C1[0,0]+dx , C1[0,1]+dy color = edge_color if type(edge_color)==list: color = edge_color[v] edgewidth = edge_width if type(edge_width)==list: edgewidth = edge_width[v] middle_index = int(len(X)/2) posA = (X[middle_index-5], Y[middle_index-5]) posB = (X[middle_index+5], Y[middle_index+5]) if dv<0.0: u = posA posA = posB posB = u try: arrow = ArrowPath(posA=posA, posB=posB, mutation_scale=arrow_scale,color=color) ax.add_patch(arrow) except: True ax.plot(X,Y, "-", linewidth=edgewidth, color=color, zorder=0, alpha=alpha)
[docs]def draw_networks(G, pos, ax, mu=0.08, edge_color="black", edge_width=1.0, edge_alpha=1.0, use_edge_weigth=False, node_width=1.0, node_size=80.0, node_border_color="#404040", node_color="#EDEDED", node_alpha=1.0, arrow_scale=20.0, loop_radius=0.0, letter="", letter_fontsize=13, letter_pos=[0.87, 0.02], letter_color="black"): """This function draws networks. **Parameters** G : Networkx Graph A Networkx ``Graph`` or ``DiGraph``. pos : dict A dictionary of nodes positions. ax : Matplotlib Axes object Draw the network in the specified Matplotlib axes. mu : float : (default=0.05) Level of curvature. Should always be positive. If zero, then edges are straight. edge_color : str or list : (default="black") If a list, then each entry matches the color of the edge. when iterated through ``edges``. If a string, then each edge will have the same color. edge_width : float or list : (default=1.0) Use this if ``use_edge_weigth==False`` for edge widths. If a list, each element must be in the same order as ``G.edges()`` edge_alpha : float : (default=1) Edges opacity. use_edge_weigth : Bool : (default=False) Use the key ``weight`` of the edges attributes to choose the thickness of the edges. node_width : Float : (default=1.0) Node border width. node_size : Float : (default=80) Controls the node size (proportional to its radius). node_border_color : String : (default="#404040") Node border color. node_color : String or list : (default="#EDEDED") Node background color. node_alpha : float : (default=1.0) Node opacity. arrow_scale : float : (default=20) Control the size of the arrows. If equals to zero, then the arrows are invisible. loop_radius : float : (default=0) If ``edges`` contains self-loops, i.e. ``edge==(nodeA, nodeA)``, then it draws a self-loop which is composed of a simple circle. The radius of the circle is controlled by ``loop_radius``. letter : string : (default="") Text that can be positioned on the figure. letter_fontsize : float : (default=13) Font size of the text . letter_pos : List : (default=[0.87,0.02]) Position of the text given in relative size of the plot. The first element is ``x``, the second is ``y``. letter_color : String : (default="black") Color of the text. **Example** .. code:: python import networkx as nx import dynamicalab.drawing as draw import matplotlib.pyplot as plt import seaborn as sns import numpy as np G = nx.erdos_renyi_graph(20,0.5) pos = nx.spring_layout(G) edges = G.edges() sns.set(style="ticks") fig = plt.figure() ax = plt.gca() node_colors = np.random.choice(['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac'], 20, replace=True) draw.draw_networks(G, pos, ax, mu=0.08, edge_color="gray", edge_width=1.5, edge_alpha=0.6, use_edge_weigth=False, node_width=1.5, node_size=100.0, node_border_color="#404040", node_color=node_colors, node_alpha=1.0, arrow_scale=0.0, loop_radius=0, letter="Example for Dynamicalab", letter_fontsize=16, letter_pos=[0.3, -0.05], letter_color="black") .. image:: /_static/assets/draw_example.png :align: center """ # Edges weights = [0]*G.number_of_edges() for i,edge in enumerate(G.edges()): if use_edge_weigth: weights[i] = G[edge[0]][edge[1]]['weight'] else: if type(edge_width)==list: weights[i] = edge_width[i] else: weights[i] = edge_width draw_curved_edges(G.edges(), pos, ax, mu=mu, edge_color=edge_color, alpha = edge_alpha, arrow_scale=arrow_scale, loopsize=loop_radius, edge_width=weights) # Nodes nodes = nx.draw_networkx_nodes(G, pos, ax=ax, node_size=node_size, node_color=node_color, linewidths=node_width) nodes.set_edgecolor(node_border_color) # Letter font = FontProperties() font.set_weight('bold') ax.text(letter_pos[0], letter_pos[1], letter, verticalalignment='bottom', horizontalalignment='left', transform=ax.transAxes, fontproperties=font, color=letter_color, fontsize=letter_fontsize) # Axis ax.axis('off') return