您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

python—networkx:各个布局的源代码

5b51 2022/1/14 8:25:23 python 字数 54858 阅读 734 来源 www.jb51.cc/python

Sourcecodefornetworkx.drawing.layout 方便学习与重新封装 \"\"\" ****** Layout ****** Nodepositioningalgorithmsforgraphdrawing.

概述

Source code for networkx.drawing.layout

方便学习与重新封装

Node positioning algorithms for graph drawing.
"""

Copyright (C) 2004-2015 by

Aric Hagberg hagberg@lanl.gov

Dan Schult dschult@colgate.edu

Pieter Swart swart@lanl.gov

All rights reserved.

BSD license.

import collections
import networkx as nx
author = """Aric Hagberg (hagberg@lanl.gov)\nDan Schult(dschult@colgate.edu)"""
all = ['circular_layout','random_layout','shell_layout','spring_layout','spectral_layout','fruchterman_reingold_layout']

def process_params(G,center,dim):

Some boilerplate code.

import numpy as np

if not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(G,nx.Graph):
    empty_graph = nx.Graph()
    empty_graph.add_nodes_from(G)
    G = empty_graph

if center is None:
    center = np.zeros(dim)
else:
    center = np.asarray(center)

if len(center) != dim:
    msg = "length of center coordinates must match dimension of layout"
    raise ValueError(msg)

return G,center

[docs]def random_layout(G,dim=2,center=None):
"""Position nodes uniformly at random in the unit square.

For every node,a position is generated by choosing each of dim
coordinates uniformly at random on the interval [0.0,1.0).

NumPy (http://scipy.org) is <a href="https://www.jb51.cc/tag/required/" target="_blank" class="keywords">required</a> for this function.

Parameters
----------
G : NetworkX graph or list of nodes
   A position will be assigned to every node in G.

dim : int
   Dimension of layout.

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
pos : dict
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.lollipop_graph(4,3)
>>> pos = nx.random_layout(G)

"""
import numpy as np

G,center = process_params(G,dim)
shape = (len(G),dim)
pos = np.random.random(shape) + center
pos = pos.astype(np.float32)
pos = dict(zip(G,pos))

return pos

[docs]def circular_layout(G,scale=1,center=None):

dim=2 only

"""Position nodes on a circle.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.circular_layout(G)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    pos = {}
elif len(G) == 1:
    pos = {G.nodes()[0]: center}
else:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,1,len(G) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),np.sin(theta)])
    pos = _rescale_layout(pos,scale=scale) + center
    pos = dict(zip(G,pos))

return pos

[docs]def shell_layout(G,nlist=None,center=None):
"""Position nodes in concentric circles.

Parameters
----------
G : NetworkX graph or list of nodes

nlist : list of lists
   List of node lists for each shell.

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> shells = [[0],[1,2,3]]
>>> pos = nx.shell_layout(G,shells)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    return {}
elif len(G) == 1:
    return {G.nodes()[0]: center}


if nlist is None:
    # draw the whole graph in one shell
    nlist = [list(G.nodes())]

if len(nlist[0]) == 1:
    # single node at center
    radius = 0.0
else:
    # else start at r=1
    radius = 1.0

npos={}
for nodes in nlist:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,len(nodes) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),scale=scale * radius / len(nlist)) + center
    npos.update(zip(nodes,pos))
    radius += 1.0

return npos

def fruchterman_reingold_layout(G,k=None,pos=None,fixed=None,iterations=50,weight='weight',scale=1.0,center=None):
"""Position nodes using Fruchterman-Reingold force-directed algorithm.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

k : float (default=None)
   Optimal distance between nodes.  If None the distance is set to
   1/sqrt(n) where n is the number of nodes.  Increase this value
   to move nodes farther apart.


pos : dict or None  optional (default=None)
   Initial positions for nodes as a dictionary with node as keys
   and values as a list or tuple.  If None,then use random initial
   positions.

fixed : list or None  optional (default=None)
  Nodes to keep fixed at initial position.

iterations : int  optional (default=50)
   Number of iterations of spring-force relaxation

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float (default=1.0)
    Scale factor for positions. The nodes are positioned
    in a <a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a> of size [0,scale] x [0,scale].

center : array-like or None
   Coordinate pair around which to center the layout.


Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spring_layout(G)

# The same using longer function name
>>> pos=nx.fruchterman_reingold_layout(G)
"""
import numpy as np

G,dim)

if fixed is not None:
    nfixed = dict(zip(G,range(len(G))))
    fixed = np.asarray([nfixed[v] for v in fixed])

if pos is not None:
    # Deter<a href="https://www.jb51.cc/tag/mine/" target="_blank" class="keywords">mine</a> size of existing domain to adjust initial positions
    dom_size = max(flatten(pos.values()))
    shape = (len(G),dim)
    pos_arr = np.random.random(shape) * dom_size + center
    for i,n in enumerate(G):
        if n in pos:
            pos_arr[i] = np.asarray(pos[n])
else:
    pos_arr=None

if len(G) == 0:
    return {}
if len(G) == 1:
    return {G.nodes()[0]: center}

try:
    # Sparse matrix
    if len(G) < 500:  # sparse solver for large graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,weight=weight,dtype='f')
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _sparse_fruchterman_reingold(A,dim,k,pos_arr,fixed,iterations)
except:
    A = nx.to_numpy_matrix(G,weight=weight)
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _fruchterman_reingold(A,iterations)
if fixed is None:
    pos = _rescale_layout(pos,scale=scale) + center
pos = dict(zip(G,pos))
return pos

spring_layout=fruchterman_reingold_layout

def _fruchterman_reingold(A,iterations=50):

Position nodes in adjacency matrix A using Fruchterman-Reingold

# Entry point for NetworkX graph is fruchterman_reingold_layout()
try:
    import numpy as np
except ImportError:
    raise ImportError("_fruchterman_reingold() requires numpy: http://scipy.org/ ")

try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")

A=np.asarray(A) # make sure we have an array instead of a matrix

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dim)),dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
# We need to calculate this in case our fixed positions force our domain
# to be much bigger than 1x1
t = max(max(pos.T[0]) - min(pos.T[0]),max(pos.T[1]) - min(pos.T[1]))*0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)
delta = np.zeros((pos.shape[0],pos.shape[0],pos.shape[1]),dtype=A.dtype)
# the inscrutable (but fast) version
# this is still O(V^2)
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods to speed this up significantly
for iteration in range(iterations):
    # matrix of difference between points
    for i in range(pos.shape[1]):
        delta[:,:,i]= pos[:,i,None]-pos[:,i]
    # distance between points
    distance=np.sqrt((delta**2).sum(axis=-1))
    # enforce minimum distance of 0.01
    distance=np.where(distance<0.01,0.01,distance)
    # displacement "force"
    displacement=np.transpose(np.transpose(delta)*\
                              (k*k/distance**2-A*distance/k))\
                              .sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=1))
    length=np.where(length<0.01,0.1,length)
    delta_pos=np.transpose(np.transpose(displacement)*t/length)
    if fixed is not None:
        # don't change positions of fixed nodes
        delta_pos[fixed]=0.0
    pos+=delta_pos
    # cool temperature
    t-=dt
return pos

def _sparse_fruchterman_reingold(A,iterations=50):

Position nodes in adjacency matrix A using Fruchterman-Reingold

# Entry point for NetworkX graph is fruchterman_reingold_layout()
# Sparse version
try:
    import numpy as np
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")
try:
    from scipy.sparse import spdiags,coo_matrix
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() scipy numpy: http://scipy.org/ ")
# make sure we have a LIst of Lists representation
try:
    A=A.tolil()
except:
    A=(coo_matrix(A)).tolil()

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# no fixed nodes
if fixed==None:
    fixed=[]

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
t=0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)

displacement=np.zeros((dim,nnodes))
for iteration in range(iterations):
    displacement*=0
    # loop over rows
    for i in range(A.shape[0]):
        if i in fixed:
            continue
        # difference between this row's node position and all others
        delta=(pos[i]-pos).T
        # distance between points
        distance=np.sqrt((delta**2).sum(axis=0))
        # enforce minimum distance of 0.01
        distance=np.where(distance<0.01,distance)
        # the adjacency matrix row
        Ai=np.asarray(A.getrowview(i).toarray())
        # displacement "force"
        displacement[:,i]+=\
            (delta*(k*k/distance**2-Ai*distance/k)).sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=0))
    length=np.where(length<0.01,length)
    pos+=(displacement*t/length).T
    # cool temperature
    t-=dt
return pos

[docs]def spectral_layout(G,center=None):
"""Position nodes using the eigenvectors of the graph Laplacian.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spectral_layout(G)

Notes
-----
Directed graphs will be considered as undirected graphs when
positioning the nodes.

For larger graphs (>500 nodes) this will use the SciPy sparse
eigenvalue solver (ARPACK).
"""
# handle some special cases that break the eigensolvers
import numpy as np

G,dim)

if len(G) <= 2:
    if len(G) == 0:
        pos = np.array([])
    elif len(G) == 1:
        pos = np.array([center])
    else:
        pos = np.array([np.zeros(dim),np.array(center)*2.0])
    return dict(zip(G,pos))
try:
    # Sparse matrix
    if len(G)< 500:  # dense solver is faster for small graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,dtype='d')
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _sparse_spectral(A,dim)
except (ImportError,ValueError):
    # Dense matrix
    A = nx.to_numpy_matrix(G,weight=weight)
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _spectral(A,dim)

pos = _rescale_layout(pos,scale) + center
pos = dict(zip(G,pos))
return pos

def _spectral(A,dim=2):

Input adjacency matrix A

# Uses dense eigenvalue solver from numpy
try:
    import numpy as np
except ImportError:
    raise ImportError("spectral_layout() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "spectral() takes an adjacency matrix as input")

# form Laplacian matrix
# make sure we have an array instead of a matrix
A=np.asarray(A)
I=np.identity(nnodes,dtype=A.dtype)
D=I*np.sum(A,axis=1) # diagonal of <a href="https://www.jb51.cc/tag/degrees/" target="_blank" class="keywords">degrees</a>
L=D-A

eigenvalues,eigenvectors=np.linalg.eig(L)
# sort and keep smallest nonzero
index=np.argsort(eigenvalues)[1:dim+1] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])

def _sparse_spectral(A,dim=2):

Input adjacency matrix A

# Uses sparse eigenvalue solver from scipy
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods here,see Koren "On spectral graph drawing"
try:
    import numpy as np
    from scipy.sparse import spdiags
except ImportError:
    raise ImportError("_sparse_spectral() requires scipy &amp; numpy: http://scipy.org/ ")
try:
    from scipy.sparse.linalg.eigen import eigsh
except ImportError:
    # scipy <0.9.0 names eigsh differently
    from scipy.sparse.linalg import eigen_symmetric as eigsh
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "sparse_spectral() takes an adjacency matrix as input")

# form Laplacian matrix
data=np.asarray(A.sum(axis=1).T)
D=spdiags(data,nnodes,nnodes)
L=D-A

k=dim+1
# number of Lanczos vectors for ARPACK solver.What is the right scaling?
ncv=max(2*k+1,int(np.sqrt(nnodes)))
# return smallest k eigenvalues and eigenvectors
eigenvalues,eigenvectors=eigsh(L,which='SM',ncv=ncv)
index=np.argsort(eigenvalues)[1:k] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])

def _rescale_layout(pos,scale=1):

rescale to (-scale,scale) in all axes

# shift origin to (0,0)
lim=0 # max coordinate for all axes
for i in range(pos.shape[1]):
    pos[:,i]-=pos[:,i].mean()
    lim=max(pos[:,i].max(),lim)
# rescale to (-scale,scale) in all directions,preserves aspect
for i in range(pos.shape[1]):
    pos[:,i]*=scale/lim
return pos

fixture for nose tests

def setup_module(module):
from nose import SkipTest
try:
import numpy
except:
raise SkipTest("NumPy not available")
try:
import scipy
except:
raise SkipTest("SciPy not available")

def flatten(l):
try:
bs = basestring
except NameError:

Py3k

    bs = str
for el in l:
    if <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,collections.Iterable) and not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,bs):
        for sub in flatten(el):
            yield sub
    else:
        yield el</code></pre><a href="https://networkx.github.io/documentation/latest/_modules/networkx/drawing/layout.html" rel="<a href="https://www.jb51.cc/tag/nofollow/" target="_blank" class="keywords">nofollow</a>"&gt;官网</a><br /><br />
import numpy as np

if not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(G,nx.Graph):
    empty_graph = nx.Graph()
    empty_graph.add_nodes_from(G)
    G = empty_graph

if center is None:
    center = np.zeros(dim)
else:
    center = np.asarray(center)

if len(center) != dim:
    msg = "length of center coordinates must match dimension of layout"
    raise ValueError(msg)

return G,center
For every node,a position is generated by choosing each of dim
coordinates uniformly at random on the interval [0.0,1.0).

NumPy (http://scipy.org) is <a href="https://www.jb51.cc/tag/required/" target="_blank" class="keywords">required</a> for this function.

Parameters
----------
G : NetworkX graph or list of nodes
   A position will be assigned to every node in G.

dim : int
   Dimension of layout.

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
pos : dict
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.lollipop_graph(4,3)
>>> pos = nx.random_layout(G)

"""
import numpy as np

G,center = process_params(G,dim)
shape = (len(G),dim)
pos = np.random.random(shape) + center
pos = pos.astype(np.float32)
pos = dict(zip(G,pos))

return pos
"""Position nodes on a circle.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.circular_layout(G)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    pos = {}
elif len(G) == 1:
    pos = {G.nodes()[0]: center}
else:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,1,len(G) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),np.sin(theta)])
    pos = _rescale_layout(pos,scale=scale) + center
    pos = dict(zip(G,pos))

return pos
Parameters
----------
G : NetworkX graph or list of nodes

nlist : list of lists
   List of node lists for each shell.

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> shells = [[0],[1,2,3]]
>>> pos = nx.shell_layout(G,shells)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    return {}
elif len(G) == 1:
    return {G.nodes()[0]: center}


if nlist is None:
    # draw the whole graph in one shell
    nlist = [list(G.nodes())]

if len(nlist[0]) == 1:
    # single node at center
    radius = 0.0
else:
    # else start at r=1
    radius = 1.0

npos={}
for nodes in nlist:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,len(nodes) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),scale=scale * radius / len(nlist)) + center
    npos.update(zip(nodes,pos))
    radius += 1.0

return npos
Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

k : float (default=None)
   Optimal distance between nodes.  If None the distance is set to
   1/sqrt(n) where n is the number of nodes.  Increase this value
   to move nodes farther apart.


pos : dict or None  optional (default=None)
   Initial positions for nodes as a dictionary with node as keys
   and values as a list or tuple.  If None,then use random initial
   positions.

fixed : list or None  optional (default=None)
  Nodes to keep fixed at initial position.

iterations : int  optional (default=50)
   Number of iterations of spring-force relaxation

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float (default=1.0)
    Scale factor for positions. The nodes are positioned
    in a <a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a> of size [0,scale] x [0,scale].

center : array-like or None
   Coordinate pair around which to center the layout.


Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spring_layout(G)

# The same using longer function name
>>> pos=nx.fruchterman_reingold_layout(G)
"""
import numpy as np

G,dim)

if fixed is not None:
    nfixed = dict(zip(G,range(len(G))))
    fixed = np.asarray([nfixed[v] for v in fixed])

if pos is not None:
    # Deter<a href="https://www.jb51.cc/tag/mine/" target="_blank" class="keywords">mine</a> size of existing domain to adjust initial positions
    dom_size = max(flatten(pos.values()))
    shape = (len(G),dim)
    pos_arr = np.random.random(shape) * dom_size + center
    for i,n in enumerate(G):
        if n in pos:
            pos_arr[i] = np.asarray(pos[n])
else:
    pos_arr=None

if len(G) == 0:
    return {}
if len(G) == 1:
    return {G.nodes()[0]: center}

try:
    # Sparse matrix
    if len(G) < 500:  # sparse solver for large graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,weight=weight,dtype='f')
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _sparse_fruchterman_reingold(A,dim,k,pos_arr,fixed,iterations)
except:
    A = nx.to_numpy_matrix(G,weight=weight)
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _fruchterman_reingold(A,iterations)
if fixed is None:
    pos = _rescale_layout(pos,scale=scale) + center
pos = dict(zip(G,pos))
return pos
# Entry point for NetworkX graph is fruchterman_reingold_layout()
try:
    import numpy as np
except ImportError:
    raise ImportError("_fruchterman_reingold() requires numpy: http://scipy.org/ ")

try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")

A=np.asarray(A) # make sure we have an array instead of a matrix

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dim)),dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
# We need to calculate this in case our fixed positions force our domain
# to be much bigger than 1x1
t = max(max(pos.T[0]) - min(pos.T[0]),max(pos.T[1]) - min(pos.T[1]))*0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)
delta = np.zeros((pos.shape[0],pos.shape[0],pos.shape[1]),dtype=A.dtype)
# the inscrutable (but fast) version
# this is still O(V^2)
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods to speed this up significantly
for iteration in range(iterations):
    # matrix of difference between points
    for i in range(pos.shape[1]):
        delta[:,:,i]= pos[:,i,None]-pos[:,i]
    # distance between points
    distance=np.sqrt((delta**2).sum(axis=-1))
    # enforce minimum distance of 0.01
    distance=np.where(distance<0.01,0.01,distance)
    # displacement "force"
    displacement=np.transpose(np.transpose(delta)*\
                              (k*k/distance**2-A*distance/k))\
                              .sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=1))
    length=np.where(length<0.01,0.1,length)
    delta_pos=np.transpose(np.transpose(displacement)*t/length)
    if fixed is not None:
        # don't change positions of fixed nodes
        delta_pos[fixed]=0.0
    pos+=delta_pos
    # cool temperature
    t-=dt
return pos
# Entry point for NetworkX graph is fruchterman_reingold_layout()
# Sparse version
try:
    import numpy as np
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")
try:
    from scipy.sparse import spdiags,coo_matrix
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() scipy numpy: http://scipy.org/ ")
# make sure we have a LIst of Lists representation
try:
    A=A.tolil()
except:
    A=(coo_matrix(A)).tolil()

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# no fixed nodes
if fixed==None:
    fixed=[]

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
t=0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)

displacement=np.zeros((dim,nnodes))
for iteration in range(iterations):
    displacement*=0
    # loop over rows
    for i in range(A.shape[0]):
        if i in fixed:
            continue
        # difference between this row's node position and all others
        delta=(pos[i]-pos).T
        # distance between points
        distance=np.sqrt((delta**2).sum(axis=0))
        # enforce minimum distance of 0.01
        distance=np.where(distance<0.01,distance)
        # the adjacency matrix row
        Ai=np.asarray(A.getrowview(i).toarray())
        # displacement "force"
        displacement[:,i]+=\
            (delta*(k*k/distance**2-Ai*distance/k)).sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=0))
    length=np.where(length<0.01,length)
    pos+=(displacement*t/length).T
    # cool temperature
    t-=dt
return pos
Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spectral_layout(G)

Notes
-----
Directed graphs will be considered as undirected graphs when
positioning the nodes.

For larger graphs (>500 nodes) this will use the SciPy sparse
eigenvalue solver (ARPACK).
"""
# handle some special cases that break the eigensolvers
import numpy as np

G,dim)

if len(G) <= 2:
    if len(G) == 0:
        pos = np.array([])
    elif len(G) == 1:
        pos = np.array([center])
    else:
        pos = np.array([np.zeros(dim),np.array(center)*2.0])
    return dict(zip(G,pos))
try:
    # Sparse matrix
    if len(G)< 500:  # dense solver is faster for small graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,dtype='d')
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _sparse_spectral(A,dim)
except (ImportError,ValueError):
    # Dense matrix
    A = nx.to_numpy_matrix(G,weight=weight)
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _spectral(A,dim)

pos = _rescale_layout(pos,scale) + center
pos = dict(zip(G,pos))
return pos
# Uses dense eigenvalue solver from numpy
try:
    import numpy as np
except ImportError:
    raise ImportError("spectral_layout() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "spectral() takes an adjacency matrix as input")

# form Laplacian matrix
# make sure we have an array instead of a matrix
A=np.asarray(A)
I=np.identity(nnodes,dtype=A.dtype)
D=I*np.sum(A,axis=1) # diagonal of <a href="https://www.jb51.cc/tag/degrees/" target="_blank" class="keywords">degrees</a>
L=D-A

eigenvalues,eigenvectors=np.linalg.eig(L)
# sort and keep smallest nonzero
index=np.argsort(eigenvalues)[1:dim+1] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])
# Uses sparse eigenvalue solver from scipy
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods here,see Koren "On spectral graph drawing"
try:
    import numpy as np
    from scipy.sparse import spdiags
except ImportError:
    raise ImportError("_sparse_spectral() requires scipy &amp; numpy: http://scipy.org/ ")
try:
    from scipy.sparse.linalg.eigen import eigsh
except ImportError:
    # scipy <0.9.0 names eigsh differently
    from scipy.sparse.linalg import eigen_symmetric as eigsh
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "sparse_spectral() takes an adjacency matrix as input")

# form Laplacian matrix
data=np.asarray(A.sum(axis=1).T)
D=spdiags(data,nnodes,nnodes)
L=D-A

k=dim+1
# number of Lanczos vectors for ARPACK solver.What is the right scaling?
ncv=max(2*k+1,int(np.sqrt(nnodes)))
# return smallest k eigenvalues and eigenvectors
eigenvalues,eigenvectors=eigsh(L,which='SM',ncv=ncv)
index=np.argsort(eigenvalues)[1:k] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])
# shift origin to (0,0)
lim=0 # max coordinate for all axes
for i in range(pos.shape[1]):
    pos[:,i]-=pos[:,i].mean()
    lim=max(pos[:,i].max(),lim)
# rescale to (-scale,scale) in all directions,preserves aspect
for i in range(pos.shape[1]):
    pos[:,i]*=scale/lim
return pos
    bs = str
for el in l:
    if <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,collections.Iterable) and not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,bs):
        for sub in flatten(el):
            yield sub
    else:
        yield el</code></pre><a href="https://networkx.github.io/documentation/latest/_modules/networkx/drawing/layout.html" rel="<a href="https://www.jb51.cc/tag/nofollow/" target="_blank" class="keywords">nofollow</a>"&gt;官网</a><br /><br />

import collections
import networkx as nx
author = """Aric Hagberg (hagberg@lanl.gov)\nDan Schult(dschult@colgate.edu)"""
all = ['circular_layout','random_layout','shell_layout','spring_layout','spectral_layout','fruchterman_reingold_layout']

def process_params(G,center,dim):

[docs]def random_layout(G,dim=2,center=None):
"""Position nodes uniformly at random in the unit square.

[docs]def circular_layout(G,scale=1,center=None):

[docs]def shell_layout(G,nlist=None,center=None):
"""Position nodes in concentric circles.

def fruchterman_reingold_layout(G,k=None,pos=None,fixed=None,iterations=50,weight='weight',scale=1.0,center=None):
"""Position nodes using Fruchterman-Reingold force-directed algorithm.

spring_layout=fruchterman_reingold_layout

def _fruchterman_reingold(A,iterations=50):

def _sparse_fruchterman_reingold(A,iterations=50):

[docs]def spectral_layout(G,center=None):
"""Position nodes using the eigenvectors of the graph Laplacian.

def _spectral(A,dim=2):

def _sparse_spectral(A,dim=2):

def _rescale_layout(pos,scale=1):

def setup_module(module):
from nose import SkipTest
try:
import numpy
except:
raise SkipTest("NumPy not available")
try:
import scipy
except:
raise SkipTest("SciPy not available")

def flatten(l):
try:
bs = basestring
except NameError:

import collections
import networkx as nx
author = """Aric Hagberg (hagberg@lanl.gov)\nDan Schult(dschult@colgate.edu)"""
all = ['circular_layout','random_layout','shell_layout','spring_layout','spectral_layout','fruchterman_reingold_layout']

def process_params(G,center,dim):

import numpy as np

if not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(G,nx.Graph):
    empty_graph = nx.Graph()
    empty_graph.add_nodes_from(G)
    G = empty_graph

if center is None:
    center = np.zeros(dim)
else:
    center = np.asarray(center)

if len(center) != dim:
    msg = "length of center coordinates must match dimension of layout"
    raise ValueError(msg)

return G,center

[docs]def random_layout(G,dim=2,center=None):
"""Position nodes uniformly at random in the unit square.

For every node,a position is generated by choosing each of dim
coordinates uniformly at random on the interval [0.0,1.0).

NumPy (http://scipy.org) is <a href="https://www.jb51.cc/tag/required/" target="_blank" class="keywords">required</a> for this function.

Parameters
----------
G : NetworkX graph or list of nodes
   A position will be assigned to every node in G.

dim : int
   Dimension of layout.

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
pos : dict
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.lollipop_graph(4,3)
>>> pos = nx.random_layout(G)

"""
import numpy as np

G,center = process_params(G,dim)
shape = (len(G),dim)
pos = np.random.random(shape) + center
pos = pos.astype(np.float32)
pos = dict(zip(G,pos))

return pos

[docs]def circular_layout(G,scale=1,center=None):

"""Position nodes on a circle.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.circular_layout(G)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    pos = {}
elif len(G) == 1:
    pos = {G.nodes()[0]: center}
else:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,1,len(G) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),np.sin(theta)])
    pos = _rescale_layout(pos,scale=scale) + center
    pos = dict(zip(G,pos))

return pos

[docs]def shell_layout(G,nlist=None,center=None):
"""Position nodes in concentric circles.

Parameters
----------
G : NetworkX graph or list of nodes

nlist : list of lists
   List of node lists for each shell.

dim : int
   Dimension of layout,currently only dim=2 is supported

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G = nx.path_graph(4)
>>> shells = [[0],[1,2,3]]
>>> pos = nx.shell_layout(G,shells)

Notes
------
This algorithm currently only works in two dimensions and does not
try to minimize edge crossings.

"""
import numpy as np

G,dim)

if len(G) == 0:
    return {}
elif len(G) == 1:
    return {G.nodes()[0]: center}


if nlist is None:
    # draw the whole graph in one shell
    nlist = [list(G.nodes())]

if len(nlist[0]) == 1:
    # single node at center
    radius = 0.0
else:
    # else start at r=1
    radius = 1.0

npos={}
for nodes in nlist:
    # Discard the extra angle since it matches 0 <a href="https://www.jb51.cc/tag/radians/" target="_blank" class="keywords">radians</a>.
    theta = np.linspace(0,len(nodes) + 1)[:-1] * 2 * np.pi
    theta = theta.astype(np.float32)
    pos = np.column_stack([np.cos(theta),scale=scale * radius / len(nlist)) + center
    npos.update(zip(nodes,pos))
    radius += 1.0

return npos

def fruchterman_reingold_layout(G,k=None,pos=None,fixed=None,iterations=50,weight='weight',scale=1.0,center=None):
"""Position nodes using Fruchterman-Reingold force-directed algorithm.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

k : float (default=None)
   Optimal distance between nodes.  If None the distance is set to
   1/sqrt(n) where n is the number of nodes.  Increase this value
   to move nodes farther apart.


pos : dict or None  optional (default=None)
   Initial positions for nodes as a dictionary with node as keys
   and values as a list or tuple.  If None,then use random initial
   positions.

fixed : list or None  optional (default=None)
  Nodes to keep fixed at initial position.

iterations : int  optional (default=50)
   Number of iterations of spring-force relaxation

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float (default=1.0)
    Scale factor for positions. The nodes are positioned
    in a <a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a> of size [0,scale] x [0,scale].

center : array-like or None
   Coordinate pair around which to center the layout.


Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spring_layout(G)

# The same using longer function name
>>> pos=nx.fruchterman_reingold_layout(G)
"""
import numpy as np

G,dim)

if fixed is not None:
    nfixed = dict(zip(G,range(len(G))))
    fixed = np.asarray([nfixed[v] for v in fixed])

if pos is not None:
    # Deter<a href="https://www.jb51.cc/tag/mine/" target="_blank" class="keywords">mine</a> size of existing domain to adjust initial positions
    dom_size = max(flatten(pos.values()))
    shape = (len(G),dim)
    pos_arr = np.random.random(shape) * dom_size + center
    for i,n in enumerate(G):
        if n in pos:
            pos_arr[i] = np.asarray(pos[n])
else:
    pos_arr=None

if len(G) == 0:
    return {}
if len(G) == 1:
    return {G.nodes()[0]: center}

try:
    # Sparse matrix
    if len(G) < 500:  # sparse solver for large graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,weight=weight,dtype='f')
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _sparse_fruchterman_reingold(A,dim,k,pos_arr,fixed,iterations)
except:
    A = nx.to_numpy_matrix(G,weight=weight)
    if k is None and fixed is not None:
       # We must adjust k by domain size for layouts that are not near 1x1
       nnodes,_ = A.shape
       k = dom_size / np.sqrt(nnodes)
    pos = _fruchterman_reingold(A,iterations)
if fixed is None:
    pos = _rescale_layout(pos,scale=scale) + center
pos = dict(zip(G,pos))
return pos

spring_layout=fruchterman_reingold_layout

def _fruchterman_reingold(A,iterations=50):

# Entry point for NetworkX graph is fruchterman_reingold_layout()
try:
    import numpy as np
except ImportError:
    raise ImportError("_fruchterman_reingold() requires numpy: http://scipy.org/ ")

try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")

A=np.asarray(A) # make sure we have an array instead of a matrix

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dim)),dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
# We need to calculate this in case our fixed positions force our domain
# to be much bigger than 1x1
t = max(max(pos.T[0]) - min(pos.T[0]),max(pos.T[1]) - min(pos.T[1]))*0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)
delta = np.zeros((pos.shape[0],pos.shape[0],pos.shape[1]),dtype=A.dtype)
# the inscrutable (but fast) version
# this is still O(V^2)
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods to speed this up significantly
for iteration in range(iterations):
    # matrix of difference between points
    for i in range(pos.shape[1]):
        delta[:,:,i]= pos[:,i,None]-pos[:,i]
    # distance between points
    distance=np.sqrt((delta**2).sum(axis=-1))
    # enforce minimum distance of 0.01
    distance=np.where(distance<0.01,0.01,distance)
    # displacement "force"
    displacement=np.transpose(np.transpose(delta)*\
                              (k*k/distance**2-A*distance/k))\
                              .sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=1))
    length=np.where(length<0.01,0.1,length)
    delta_pos=np.transpose(np.transpose(displacement)*t/length)
    if fixed is not None:
        # don't change positions of fixed nodes
        delta_pos[fixed]=0.0
    pos+=delta_pos
    # cool temperature
    t-=dt
return pos

def _sparse_fruchterman_reingold(A,iterations=50):

# Entry point for NetworkX graph is fruchterman_reingold_layout()
# Sparse version
try:
    import numpy as np
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(
        "fruchterman_reingold() takes an adjacency matrix as input")
try:
    from scipy.sparse import spdiags,coo_matrix
except ImportError:
    raise ImportError("_sparse_fruchterman_reingold() scipy numpy: http://scipy.org/ ")
# make sure we have a LIst of Lists representation
try:
    A=A.tolil()
except:
    A=(coo_matrix(A)).tolil()

if pos==None:
    # random initial positions
    pos=np.asarray(np.random.random((nnodes,dtype=A.dtype)
else:
    # make sure positions are of same type as matrix
    pos=pos.astype(A.dtype)

# no fixed nodes
if fixed==None:
    fixed=[]

# optimal distance between nodes
if k is None:
    k=np.sqrt(1.0/nnodes)
# the initial "temperature"  is about .1 of domain area (=1x1)
# this is the largest step allowed in the dynamics.
t=0.1
# simple cooling scheme.
# linearly step down by dt on each iteration so last iteration is size dt.
dt=t/float(iterations+1)

displacement=np.zeros((dim,nnodes))
for iteration in range(iterations):
    displacement*=0
    # loop over rows
    for i in range(A.shape[0]):
        if i in fixed:
            continue
        # difference between this row's node position and all others
        delta=(pos[i]-pos).T
        # distance between points
        distance=np.sqrt((delta**2).sum(axis=0))
        # enforce minimum distance of 0.01
        distance=np.where(distance<0.01,distance)
        # the adjacency matrix row
        Ai=np.asarray(A.getrowview(i).toarray())
        # displacement "force"
        displacement[:,i]+=\
            (delta*(k*k/distance**2-Ai*distance/k)).sum(axis=1)
    # update positions
    length=np.sqrt((displacement**2).sum(axis=0))
    length=np.where(length<0.01,length)
    pos+=(displacement*t/length).T
    # cool temperature
    t-=dt
return pos

[docs]def spectral_layout(G,center=None):
"""Position nodes using the eigenvectors of the graph Laplacian.

Parameters
----------
G : NetworkX graph or list of nodes

dim : int
   Dimension of layout

weight : string or None   optional (default='weight')
    The edge attribute that holds the numerical value used for
    the edge weight.  If None,then all edge weights are 1.

scale : float
    Scale factor for positions

center : array-like or None
   Coordinate pair around which to center the layout.

Returns
-------
dict :
   A dictionary of positions keyed by node

Examples
--------
>>> G=nx.path_graph(4)
>>> pos=nx.spectral_layout(G)

Notes
-----
Directed graphs will be considered as undirected graphs when
positioning the nodes.

For larger graphs (>500 nodes) this will use the SciPy sparse
eigenvalue solver (ARPACK).
"""
# handle some special cases that break the eigensolvers
import numpy as np

G,dim)

if len(G) <= 2:
    if len(G) == 0:
        pos = np.array([])
    elif len(G) == 1:
        pos = np.array([center])
    else:
        pos = np.array([np.zeros(dim),np.array(center)*2.0])
    return dict(zip(G,pos))
try:
    # Sparse matrix
    if len(G)< 500:  # dense solver is faster for small graphs
        raise ValueError
    A = nx.to_scipy_sparse_matrix(G,dtype='d')
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _sparse_spectral(A,dim)
except (ImportError,ValueError):
    # Dense matrix
    A = nx.to_numpy_matrix(G,weight=weight)
    # Symmetrize directed graphs
    if G.is_directed():
        A = A + np.transpose(A)
    pos = _spectral(A,dim)

pos = _rescale_layout(pos,scale) + center
pos = dict(zip(G,pos))
return pos

def _spectral(A,dim=2):

# Uses dense eigenvalue solver from numpy
try:
    import numpy as np
except ImportError:
    raise ImportError("spectral_layout() requires numpy: http://scipy.org/ ")
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "spectral() takes an adjacency matrix as input")

# form Laplacian matrix
# make sure we have an array instead of a matrix
A=np.asarray(A)
I=np.identity(nnodes,dtype=A.dtype)
D=I*np.sum(A,axis=1) # diagonal of <a href="https://www.jb51.cc/tag/degrees/" target="_blank" class="keywords">degrees</a>
L=D-A

eigenvalues,eigenvectors=np.linalg.eig(L)
# sort and keep smallest nonzero
index=np.argsort(eigenvalues)[1:dim+1] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])

def _sparse_spectral(A,dim=2):

# Uses sparse eigenvalue solver from scipy
# <a href="https://www.jb51.cc/tag/Could/" target="_blank" class="keywords">Could</a> use multilevel methods here,see Koren "On spectral graph drawing"
try:
    import numpy as np
    from scipy.sparse import spdiags
except ImportError:
    raise ImportError("_sparse_spectral() requires scipy &amp; numpy: http://scipy.org/ ")
try:
    from scipy.sparse.linalg.eigen import eigsh
except ImportError:
    # scipy <0.9.0 names eigsh differently
    from scipy.sparse.linalg import eigen_symmetric as eigsh
try:
    nnodes,_=A.shape
except AttributeError:
    raise nx.NetworkXError(\
        "sparse_spectral() takes an adjacency matrix as input")

# form Laplacian matrix
data=np.asarray(A.sum(axis=1).T)
D=spdiags(data,nnodes,nnodes)
L=D-A

k=dim+1
# number of Lanczos vectors for ARPACK solver.What is the right scaling?
ncv=max(2*k+1,int(np.sqrt(nnodes)))
# return smallest k eigenvalues and eigenvectors
eigenvalues,eigenvectors=eigsh(L,which='SM',ncv=ncv)
index=np.argsort(eigenvalues)[1:k] # 0 index is zero eigenvalue
return np.real(eigenvectors[:,index])

def _rescale_layout(pos,scale=1):

# shift origin to (0,0)
lim=0 # max coordinate for all axes
for i in range(pos.shape[1]):
    pos[:,i]-=pos[:,i].mean()
    lim=max(pos[:,i].max(),lim)
# rescale to (-scale,scale) in all directions,preserves aspect
for i in range(pos.shape[1]):
    pos[:,i]*=scale/lim
return pos

def setup_module(module):
from nose import SkipTest
try:
import numpy
except:
raise SkipTest("NumPy not available")
try:
import scipy
except:
raise SkipTest("SciPy not available")

def flatten(l):
try:
bs = basestring
except NameError:

    bs = str
for el in l:
    if <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,collections.Iterable) and not <a href="https://www.jb51.cc/tag/isinstance/" target="_blank" class="keywords">isinstance</a>(el,bs):
        for sub in flatten(el):
            yield sub
    else:
        yield el</code></pre><a href="https://networkx.github.io/documentation/latest/_modules/networkx/drawing/layout.html" rel="<a href="https://www.jb51.cc/tag/nofollow/" target="_blank" class="keywords">nofollow</a>"&gt;官网</a><br /><br />

总结

以上是编程之家为你收集整理的python—networkx:各个布局的源代码全部内容,希望文章能够帮你解决python—networkx:各个布局的源代码所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶