2

这是我之前在此处发布的问题的后续内容,以可视化图表中的边缘攻击。

下面的代码已作为我之前帖子的答案发布

import matplotlib.pyplot as plt
import networkx as nx

H = nx.gnm_random_graph(n=8, m=9, seed=5)  # generate a random graph
H.add_edges_from([('I', 1), (5, 'O')])  # adding input/output nodes
pos = nx.spring_layout(H, iterations=200)  # find good positions for nodes


def attack(G, edge, color):
    G.remove_edge(*edge)  # first remove the edge

    # check if another could be also impacted
    if G.degree[edge[0]] == 1:
        neighbor = [n for n in G.neighbors(edge[0])][0]
        impacted_edge = (edge[0], neighbor)

    elif G.degree[edge[1]] == 1:
        neighbor = [n for n in G.neighbors(edge[1])][0]
        impacted_edge = (edge[1], neighbor)

    else:
        impacted_edge = None

    G.add_edge(*edge)  # put back the edge to redraw it

    # redraw the attacked edge (solid) and the possible impacted one (dashed)
    if impacted_edge:
        nx.draw_networkx_edges(
            G,
            edgelist=[impacted_edge],
            pos=pos,
            edge_color=color,
            style='dashed',
            width=4
        )
    nx.draw_networkx_edges(
        G,
        edgelist=[edge],
        pos=pos,
        edge_color=color,
        label=f'attack {edge[0]}{edge[1]}',
        style='solid',
        width=4
    )


# attack some edges
attack(H, (6, 4), color='red')
attack(H, (3, 6), color='blue')
attack(H, (1, 2), color='green')

nx.draw(H, pos, node_size=700, with_labels=True, node_color='gray')

plt.legend()
plt.show()

在此处输入图像描述

实线表示受到攻击的边缘,相同颜色的虚线表示由于特定攻击而受到影响的相邻边缘。

答案会有所帮助,但是当受影响的边缘重叠时会出现问题。

例子,

 attack(H, (6, 4), color='red')
 attack(H, (5, 4), color='yellow')

在此处输入图像描述

颜色重叠,很难想象。如果我们可以画出表示受影响/被攻击边缘的虚线彼此相邻,而不会像这张图片中显示的那样重叠,那将是很好的。

将不胜感激有关如何改进此可视化的建议!

编辑:下面发布的答案对 2D 网络非常有用,我仍在寻找方法来扩展它以pos在 pyvis 中可视化 3D 网络(即当 x、y、z 坐标可用作节点的属性时)。建议将不胜感激。

4

1 回答 1

4

避免图形中重叠边的另一个好方法是使用pyvis,但是这里的问题是它只支持有向图中的平行边。一种解决方案是将您的图形可视化为有向图形,然后调整边缘选项以使箭头不明显。将以下代码段添加到上述代码的末尾。

from pyvis.network import Network


N = Network(bgcolor='#222222', font_color='white', directed=True)
N.set_edge_smooth('dynamic')

for n in H.nodes:
    N.add_node(n, color='gray')

for e in H.edges:
    N.add_edge(e[0], e[1], color='gray', width=0)

for e in impacted_edges:
    N.add_edge(e[0], e[1], color=e[2], width=1, dashes=True)

for e in edges:
    N.add_edge(e[0], e[1], color=e[2], width=1)

N.set_options('''
var options = {
  "edges": {
    "arrows": {
      "to": {
        "enabled": true,
        "scaleFactor": 0
      },
      "middle": {
        "enabled": true,
        "scaleFactor": 0
      },
      "from": {
        "enabled": true,
        "scaleFactor": 0
      }
    },
    "color": {
      "inherit": true
    },
    "smooth": {
      "forceDirection": "none"
    }
  },
  "physics": {
    "minVelocity": 0.75
  }
}
''')

N.write_html('example_graph.html')

您可以在以下图表中找到example_graph.html在此处输入图像描述

于 2020-09-14T12:48:13.433 回答