Natasha
Natasha

Reputation: 1521

What's the best way to visualize link attacks in 3D

This is a follow up to my previous question posted here to visualize edge attacks in graphs.

The code below has been posted as an answer to my previous post

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()

enter image description here

The solid lines indicate the edges that are attacked and the dashed lines of same color indicate the neighboring edges that are impacted due to a specific attack.

The answer helps but there is a problem when the impacted edges overlap.

Example,

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

enter image description here

The colors overlap and it's hard to visualize. If we can draw the dashed lines that indicate the impacted/attacked edges next to each other, without overlapping like shown in this image that will be good.

Suggestions on how to improve this visualization will be greatly appreciated!

EDIT: The answer posted below is really useful for 2D networks and I am still looking for ways to extend this to visualize 3D networks (i.e when x,y,z coordinates are available as pos attributes of a node) in pyvis. Suggestions will be greatly appreciated.

Upvotes: 2

Views: 1538

Answers (1)

Azim Mazinani
Azim Mazinani

Reputation: 733

Another good way to avoid the overlapping edges in your graph is to use pyvis, however the problem here is that it only supports parallel edges in directed graphs. One solution is to visualize your graph as a directed one and then tweak the edge options to make the arrow unnoticeable. Add the following snippet to end of the above code.

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')

You can find the following graph in example_graph.html: enter image description here

Upvotes: 4

Related Questions