网络分析网络的子图

时间:2014-02-20 00:54:21

标签: python networking matplotlib networkx

我一直在研究其他网络密谋帖,但我一直很难适应我的问题。

1)如何在没有PREDEFINED数量的对象的情况下创建带有网络图的子图?该函数动态地抓取它。

2)例如,是否有一种简单的方法可以通过限制超过2的权重来过滤网络图?或者我是否必须编辑网络对象才能这样做?

更新#2:我想出了一种按度数过滤的方法(见下文)。 我更想知道是否有更好的方法可以让我的网络数据更容易理解?

nol的格式为[[Year,networkobject],[Year,networkobject]]

def standardgraph_multiyear(nol, minimumdegree):
"""
Plots multiple graphs based on year
nol = takes in a LIST of [year, network object]
minimum = takes in a digit to filter nodes by degree
"""

#Each iteration prints a new subplot 
numrows = len(nol)
fig = plt.figure(figsize=(10,60))    
for i, val in enumerate(nol):
    gloc = numrows,1,i+1
    plt.subplot(numrows, 1, i+1)

    if minimumdegree > 0:
        outdeg = val[1].degree()
        to_keep = [n for n in outdeg if outdeg[n] > minimumdegree]
        mingraph = val[1].subgraph(to_keep)
        pos = nx.spring_layout(mingraph, iterations=200)
        nx.draw(mingraph, pos, font_size=8, with_labels=True)
        nx.draw_networkx_edges(mingraph, pos, alpha=.2)
        nx.draw_networkx_nodes(mingraph, pos, node_size=60, font_size =8, labels=True)
        nx.draw_networkx_labels(mingraph, pos, font_color='k', font_size=8)
        plt.title("Year {0}".format(val[0]), loc = 'center', fontsize=20)

    if minimumdegree == 0:
        outdeg = val[1].degree()
        to_keep = [n for n in outdeg if outdeg[n] > minimumdegree]
        mingraph = val[1].subgraph(to_keep)
        pos = nx.spring_layout(mingraph, iterations=200)
        nx.draw(mingraph, pos, font_size=8, with_labels=True)
        nx.draw_networkx_edges(mingraph, pos, alpha=.2)
        nx.draw_networkx_nodes(mingraph, pos, node_size=60, font_size =8, labels=True)
        nx.draw_networkx_labels(mingraph, pos, font_color='k', font_size=8)
        plt.title("Year {0}".format(val[0]), loc = 'center', fontsize=20)
return 

fig.savefig('out.png',dpi = 100)

1 个答案:

答案 0 :(得分:4)

您的超出范围错误可能来自对plt.subplot(221+i)的调用,因为您似乎并不将i限制为< 4;因此matplotlib不知道你打算引用哪个子图?

(你似乎也有一些相互矛盾的代码组合在一起:调用plt.subplots(1,1),后来请求2x2网格。

different question中,我使用了更基本的plt.subplot(xxx)语法来生成多个子图(在networkx的four grids example之后)。但您也可以按照下图所示进行操作,将ax=关键字参数设置为已存在的轴组。请注意在渲染到每个轴之前调用sca(),这是我需要使其工作的。

我还展示了一种过滤下面显示的边缘的方法,并且它不需要修改底层图形:相反,您可以根据图形中的数据构建所需的边缘线宽,并将其用作draw_networkx_edges的论点。

编辑(重新更新的问题):示例代码现在包含如何处理未知数量的网络的更明确的说明。

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

n = 15; m = 40                        # graph size
L = np.random.choice(xrange(n), 2*m)  # select some edge destinations
weights = 0.5 + 5 * np.random.rand(m) # give each edge a weight


G = nx.Graph()                           # create a graph object
G.add_nodes_from(xrange(n))              # add n nodes to it
for i, (fr, to) in enumerate(zip(L[1::2], L[::2])): 
  G.add_edge(fr, to, weight=weights[i])  # add each edge

# use one of the edge properties to control line thickness
edgewidth = [ d['weight'] for (u,v,d) in G.edges(data=True)]

# and create a filtered version (still need an entry for each edge)
w_threshold = 2
edgewidth_filtered = [ d['weight'] if d['weight'] > w_threshold else 0
                      for (u,v,d) in G.edges(data=True)]

# alt. filtering - all edges that meet some criterion are displayed uniformly 
binary_filtered_edges = [ 1 if d['weight'] > w_threshold else 0
                      for (u,v,d) in G.edges(data=True)]

titles = [ 'edges drawn with lineweight=1', 'edge width from edge weight',
  'edge width from edge weight, only strong edges',
  'strong edges shown as lineweight=1', ]

edge_display_params = [ np.ones(len(edgewidth),), edgewidth,  
  edgewidth_filtered, binary_filtered_edges,]

# to illustrate drawing an unknown number of graphs, add some repeats repeats
n_extra = np.random.randint(0, 5)
indices = range(len(edge_display_params)) * 3
indices = indices[len(edge_display_params) + n_extra:]

# layout
pos = nx.spring_layout(G, iterations=50)
pos = nx.circular_layout(G)
#pos = nx.random_layout(G)

# rendering
fig = plt.figure(1); plt.clf()
# compute a grid size that will fit all graphs on it (couple blanks likely)
nr = int(np.ceil(np.sqrt(len(indices))))
fig, ax = plt.subplots(nr, nr, num=1)

for i, j in enumerate(indices):
    # dereference index into valid data (needed here since some repeated rather
    # than creating more, to illustrate handling unknown amount of data)
    k = indices[j]
    widths = edge_display_params[k]
    # compute index for the subplot, and set this subplot as current
    ix = np.unravel_index(i, ax.shape)
    plt.sca(ax[ix])
    # draw all nodes homogeneously, and edge weights as filtered
    nx.draw_networkx_nodes(G, pos, ax=ax[ix])
    nx.draw_networkx_edges(G, pos, width=widths, ax=ax[ix],)

    ax[ix].set_title(titles[k], fontsize=10)
    ax[ix].set_axis_off()

plt.show()

edge line thickness based on data

此示例使用相同的输入图形四次,但显然您可以将单个滤镜应用于不同的图形(通过在绘图循环内进行过滤),而不是应用不同的滤镜。


下面显示了一个创建额外4个图表的运行,因此我们有一个未使用的窗格:

unknown number of graphs