文章目录

  • 创建图表
  • 节点
  • 检查图的元素
  • 从图中删除元素
  • 使用图构造函数
  • 什么用作节点和边
  • 访问边和邻居
  • 向图、节点和边添加属性
  • 图形属性
  • 节点属性
  • 边缘属性
  • 多图
  • 图生成器和图操作
  • 1. 应用经典的图操作,例如:
  • 2. 使用对经典小图之一的调用,例如,
  • 3. 对经典图使用(构造性)生成器,例如,
  • 4. 使用随机图生成器,例如,
  • 5. 使用常见的图形格式读取存储在文件中的图形
  • 绘制图形
  • 创建图表

    创建一个没有节点和边的空图。

    import networkx as nx
    G = nx.Graph()
    

    根据定义,“Graph”是节点(顶点)的集合以及
    识别节点对(称为边、链接等)。 在 NetworkX 中,节点可以
    是任何 hashable 对象,例如文本字符串、图像、XML 对象,
    另一个 Graph、自定义节点对象等。

    节点

    G可以通过多种方式增长。 NetworkX 包括许多
    图形生成器函数和
    以多种格式读取和写入图形的工具。
    首先,我们将看看简单的操作。 您可以添加一个节点
    一次,

    G.add_node(1)
    

    或从任何 iterable 容器添加节点,例如列表

    G.add_nodes_from([2, 3])
    

    还可以添加节点以及节点
    如果容器产生表单的 2 元组,则属性
    (node, node_attribute_dict):

    >>> G.add_nodes_from([
    ...     (4, {"color": "red"}),
    ...     (5, {"color": "green"}),
    ... ])
    

    节点属性将在下面进一步讨论。

    一个图中的节点可以合并到另一个图中:

    H = nx.path_graph(10)
    G.add_nodes_from(H)
    

    G 现在包含 H 的节点作为 G 的节点。
    相比之下,您可以将图形 H用作G中的节点。

    G.add_node(H)
    

    G现在包含H作为一个节点。 这种灵活性非常强大,因为
    它允许图形图形、文件图形、函数图形等等。
    值得考虑如何构建您的应用程序,以便节点
    是有用的实体。 当然你总是可以在G中使用唯一标识符
    并且有一个单独的字典,由标识符键控到节点信息,如果
    你比较喜欢。

    G 也可以通过一次添加一条边来增长,

    G.add_edge(1, 2)
    e = (2, 3)
    G.add_edge(*e)  # unpack edge tuple*
    

    通过添加边列表,

    G.add_edges_from([(1, 2), (1, 3)])
    

    或者通过添加任何边缘。 ebunch 是任何可迭代的
    边缘元组的容器。 边元组可以是节点的 2 元组或 3 元组
    带有 2 个节点,后跟一个边属性字典,例如,
    (2, 3, {'weight': 3.1415})。 进一步讨论边缘属性
    以下。

    G.add_edges_from(H.edges)
    

    There are no complaints when adding existing nodes or edges. For example,
    after removing all nodes and edges,

    G.clear()
    

    我们添加新的节点/边,NetworkX 会悄悄地忽略任何
    已经存在。

    G.add_edges_from([(1, 2), (1, 3)])
    G.add_node(1)
    G.add_edge(1, 2)
    G.add_node("spam")        # adds node "spam"
    G.add_nodes_from("spam")  # adds 4 nodes: 's', 'p', 'a', 'm'
    G.add_edge(3, 'm')
    

    在此阶段,图 G 由 8 个节点和 3 个边组成,如下所示:

    G.number_of_nodes()
    G.number_of_edges()
    
    3
    
    DG = nx.DiGraph()
    DG.add_edge(2, 1)   # adds the nodes in order 2, 1
    DG.add_edge(1, 3)
    DG.add_edge(2, 4)
    DG.add_edge(1, 2)
    assert list(DG.successors(2)) == [1, 4]
    assert list(DG.edges) == [(2, 1), (2, 4), (1, 3), (1, 2)]
    

    检查图的元素

    我们可以检查节点和边。 四个基本图形属性有助于
    报告:G.nodesG.edgesG.adjG.degree。 这些
    是节点、边、邻居(邻接)和度的类似集合的视图
    图中的节点数。 它们提供持续更新的只读视图
    图结构。 它们也类似于 dict,因为您可以查找节点
    通过视图和边缘数据属性并使用数据属性进行迭代
    使用方法.items().data()
    如果您想要一个特定的容器类型而不是一个视图,您可以指定一个。
    这里我们使用列表,尽管集合、字典、元组和其他容器可能是
    在其他情况下更好。

    list(G.nodes)
    list(G.edges)
    list(G.adj[1])  # or list(G.neighbors(1))
    G.degree[1]  # the number of edges incident to 1
    
    2
    

    可以指定从所有节点的子集中报告边和度
    使用 nbunch。 nbunch 是以下任何一个:None(意味着所有节点),
    一个节点,或一个可迭代的节点容器,它本身不是
    图形。

    G.edges([2, 'm'])
    G.degree([2, 3])
    
    DegreeView({2: 1, 3: 2})
    

    从图中删除元素

    可以以与添加类似的方式从图中删除节点和边。
    使用方法
    Graph.remove_node(),
    Graph.remove_nodes_from(),
    Graph.remove_edge()

    Graph.remove_edges_from(),例如

    G.remove_node(2)
    G.remove_nodes_from("spam")
    list(G.nodes)
    G.remove_edge(1, 3)
    

    使用图构造函数

    图形对象不必增量构建 – 数据指定
    图结构可以直接传递给各种构造函数
    图类。
    通过实例化其中一个图来创建图结构时
    类,您可以指定多种格式的数据。

    G.add_edge(1, 2)
    H = nx.DiGraph(G)  # create a DiGraph using the connections from G
    list(H.edges())
    edgelist = [(0, 1), (1, 2), (2, 3)]
    H = nx.Graph(edgelist)  # create a graph from an edge list
    list(H.edges())
    adjacency_dict = {0: (1, 2), 1: (0, 2), 2: (0, 1)}
    H = nx.Graph(adjacency_dict)  # create a Graph dict mapping nodes to nbrs
    list(H.edges())
    
    [(0, 1), (0, 2), (1, 2)]
    

    什么用作节点和边

    您可能会注意到节点和边未指定为 NetworkX
    对象。 这使您可以自由地使用有意义的项目作为节点和
    边缘。 最常见的选择是数字或字符串,但节点可以
    是任何可散列对象(“None”除外),并且可以关联边
    使用G.add_edge(n1, n2, object=x)的任何对象x

    例如,n1n2 可以是来自 RCSB Protein 的蛋白质对象
    数据库,“x”可以指出版物的 XML 记录,详细说明
    他们相互作用的实验观察。

    我们发现这个异能非常有用,但它的滥用
    除非熟悉 Python,否则可能会导致令人惊讶的行为。
    如果有疑问,请考虑使用 convert_node_labels_to_integers() 来获得
    带有整数标签的更传统的图形。

    访问边和邻居

    除了视图Graph.edgesGraph.adj
    使用下标符号可以访问边和邻居。

    G = nx.Graph([(1, 2, {"color": "yellow"})])
    G[1]  # same as G.adj[1]
    G[1][2]
    G.edges[1, 2]
    
    {'color': 'yellow'}
    

    您可以使用下标符号获取/设置边的属性
    如果边缘已经存在。

    G.add_edge(1, 3)
    G[1][3]['color'] = "blue"
    G.edges[1, 2]['color'] = "red"
    G.edges[1, 2]
    
    {'color': 'red'}
    

    所有(节点,邻接)对的快速检查是使用
    G.adjacency()G.adj.items()
    请注意,对于无向图,邻接迭代会看到每条边两次。

    FG = nx.Graph()
    FG.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)])
    for n, nbrs in FG.adj.items():
        for nbr, eattr in nbrs.items():
            wt = eattr['weight']
            if wt < 0.5: print(f"({n}, {nbr}, {wt:.3})")
    
    (1, 2, 0.125)
    (2, 1, 0.125)
    (3, 4, 0.375)
    (4, 3, 0.375)
    

    使用 edge 属性可以方便地访问所有边。

    for (u, v, wt) in FG.edges.data('weight'):
        if wt < 0.5:
            print(f"({u}, {v}, {wt:.3})")
    
    (1, 2, 0.125)
    (3, 4, 0.375)
    

    向图、节点和边添加属性

    诸如权重、标签、颜色或任何您喜欢的 Python 对象之类的属性,
    可以附加到图、节点或边。

    每个图、节点和边都可以在关联的
    属性字典(键必须是可散列的)。 默认情况下,这些是空的,
    但是可以使用 add_edgeadd_node 或直接添加或更改属性
    操作名为“G.graph”、“G.nodes”和
    图形“G”的“G.edges”。

    图形属性

    创建新图形时分配图形属性

    G = nx.Graph(day="Friday")
    G.graph
    
    {'day': 'Friday'}
    

    或者您可以稍后修改属性

    G.graph['day'] = "Monday"
    G.graph
    
    {'day': 'Monday'}
    

    节点属性

    使用 add_node()add_nodes_from()G.nodes 添加节点属性

    G.add_node(1, time='5pm')
    G.add_nodes_from([3], time='2pm')
    G.nodes[1]
    G.nodes[1]['room'] = 714
    G.nodes.data()
    
    NodeDataView({1: {'time': '5pm', 'room': 714}, 3: {'time': '2pm'}})
    

    请注意,将节点添加到 G.nodes 不会将其添加到图形中,请使用
    G.add_node() 添加新节点。 边缘也是如此。

    边缘属性

    使用 add_edge()add_edges_from() 添加/更改边属性,
    或下标符号。

    G.add_edge(1, 2, weight=4.7 )
    G.add_edges_from([(3, 4), (4, 5)], color='red')
    G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
    G[1][2]['weight'] = 4.7
    G.edges[3, 4]['weight'] = 4.2
    

    特殊属性 weight 应该是数字,因为它被使用
    需要加权边的算法。

    有向图

    DiGraph 类提供特定的附加方法和属性
    到有向边,例如,
    DiGraph.out_edgesDiGraph.in_degree
    DiGraph.predecessorsDiGraph.successors 等。
    为了让算法能够轻松地处理这两个类,有向版本的
    neighbors 等价于
    successorsdegree 报告总和
    in_degreeout_degree 即使有时感觉不一致。

    DG = nx.DiGraph()
    DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)])
    DG.out_degree(1, weight='weight')
    DG.degree(1, weight='weight')
    list(DG.successors(1))
    list(DG.neighbors(1))
    
    [2]
    

    一些算法仅适用于有向图,而其他算法效果不佳
    为有向图定义。 确实有肿块导向的倾向
    和无向图放在一起是危险的。 如果你想治疗
    对于某些测量,您可能应该将有向图视为无向图
    使用 Graph.to_undirected() 或使用

    H = nx.Graph(G)  # create an undirected graph H from a directed graph G
    

    多图

    NetworkX 为允许多边的图提供类
    任意一对节点之间。 MultiGraph
    多有向图
    类允许您添加相同的边缘两次,可能具有不同的
    边缘数据。 这对于某些应用程序来说可能很强大,但许多
    算法在这样的图上没有很好的定义。
    在结果明确的地方,
    例如,MultiGraph.degree() 我们提供了这个函数。 否则你
    应该以进行测量的方式转换为标准图形
    定义明确。

    MG = nx.MultiGraph()
    MG.add_weighted_edges_from([(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)])
    dict(MG.degree(weight='weight'))
    GG = nx.Graph()
    for n, nbrs in MG.adjacency():
        for nbr, edict in nbrs.items():
            minvalue = min([d['weight'] for d in edict.values()])
            GG.add_edge(n, nbr, weight = minvalue)
    
    nx.shortest_path(GG, 1, 3)
    
    [1, 2, 3]
    

    图生成器和图操作

    除了逐节点或逐边构造图外,它们
    也可以由

    1. 应用经典的图操作,例如:

    2. 使用对经典小图之一的调用,例如,

    3. 对经典图使用(构造性)生成器,例如,

    像这样:

    K_5 = nx.complete_graph(5)
    K_3_5 = nx.complete_bipartite_graph(3, 5)
    barbell = nx.barbell_graph(10, 10)
    lollipop = nx.lollipop_graph(10, 20)
    

    4. 使用随机图生成器,例如,

    像这样:

    er = nx.erdos_renyi_graph(100, 0.15)
    ws = nx.watts_strogatz_graph(30, 3, 0.1)
    ba = nx.barabasi_albert_graph(100, 5)
    red = nx.random_lobster(100, 0.9, 0.9)
    

    5. 使用常见的图形格式读取存储在文件中的图形

    NetworkX 支持许多流行的格式,例如边缘列表、邻接列表、
    GML、GraphML、pickle、LEDA 等。

    nx.write_gml(red, "path.to.file")
    mygraph = nx.read_gml("path.to.file")
    

    有关图形格式的详细信息,请参阅阅读和编写图形
    对于图形生成器功能,请参阅图形生成器

    分析图表

    可以使用各种图论来分析 G 的结构
    功能,例如:

    G = nx.Graph()
    G.add_edges_from([(1, 2), (1, 3)])
    G.add_node("spam")       # adds node "spam"
    list(nx.connected_components(G))
    sorted(d for n, d in G.degree())
    nx.clustering(G)
    
    {1: 0, 2: 0, 3: 0, 'spam': 0}
    

    一些具有大输出的函数迭代 (node, value) 2 元组。
    如果您愿意,这些很容易存储在 dict 结构中。

    sp = dict(nx.all_pairs_shortest_path(G))
    sp[3]
    
    {3: [3], 1: [3, 1], 2: [3, 1, 2]}
    

    有关图算法的详细信息,请参阅算法
    支持的。

    绘制图形

    NetworkX 主要不是图形绘图包,而是基本绘图
    Matplotlib 以及使用开源 Graphviz 软件的接口
    包都包括在内。 这些是 networkx.drawing 的一部分
    模块,如果可能,将被导入。

    首先导入 Matplotlib 的绘图界面(pylab 也可以)

    import matplotlib.pyplot as plt
    

    测试nx_pylab的导入是否成功绘制G
    使用其中之一

    G = nx.petersen_graph()
    subax1 = plt.subplot(121)
    nx.draw(G, with_labels=True, font_weight='bold')
    subax2 = plt.subplot(122)
    nx.draw_shell(G, nlist=[range(5, 10), range(5)], with_labels=True, font_weight='bold')
    

    绘制到交互式显示器时。 请注意,您可能需要发出
    Matplotlib

    plt.show()
    

    命令,如果您不在交互模式下使用 matplotlib(请参阅
    这个 Matplotlib 常见问题解答)。

    options = {
        'node_color': 'black',
        'node_size': 100,
        'width': 3,
    }
    subax1 = plt.subplot(221)
    nx.draw_random(G, **options)
    subax2 = plt.subplot(222)
    nx.draw_circular(G, **options)
    subax3 = plt.subplot(223)
    nx.draw_spectral(G, **options)
    subax4 = plt.subplot(224)
    nx.draw_shell(G, nlist=[range(5,10), range(5)], **options)
    

    您可以通过 draw_networkx()
    通过“布局模块”进行布局。
    您可以通过draw_shell() 使用多个shell。

    G = nx.dodecahedral_graph()
    shells = [[2, 3, 4, 5, 6], [8, 1, 0, 19, 18, 17, 16, 15, 14, 7], [9, 10, 11, 12, 13]]
    nx.draw_shell(G, nlist=shells, **options)
    

    要将图纸保存到文件,请使用,例如

    nx.draw(G)
    plt.savefig("path.png")
    

    此函数写入本地目录中的文件“path.png”。 如果 Graphviz 和
    PyGraphviz 或 pydot,在您的系统上可用,您也可以使用
    networkx.drawing.nx_agraph.graphviz_layout
    networkx.drawing.nx_pydot.graphviz_layout 获取节点位置,或者写
    点格式的图形以供进一步处理。

    from networkx.drawing.nx_pydot import write_dot
    pos = nx.nx_agraph.graphviz_layout(G)
    nx.draw(G, pos=pos)
    write_dot(G, 'file.dot')
    

    networkx官网:https://networkx.org/

    来源:ACxz

    物联沃分享整理
    物联沃-IOTWORD物联网 » networkx 中文学习手册

    发表评论