问题描述
我有一个Networkx图形,如下图(image source)
我进行边缘攻击,并观察结果子图的节点上值的变化。
例如, 如果我攻击边缘(a,2):边缘(a,2)和(2,1)将被移除。稍微说明一下,当边缘(a,2)受到攻击时,节点2的度数
上述攻击导致产生一个子图
每次攻击边缘时,观察到的标记为e
的终端节点的值都会随时间变化。假设我执行了5次(攻击= 5)攻击,我有一个time x attack
矩阵(时间= 25,攻击= 5),它存储节点e
的时间序列数据。
我想就如何可视化这些攻击对节点e
的值随时间变化的影响提出建议。
编辑:
您希望能够从自己的帐户中看到或识别哪些信息 可视化?
我想看看在哪个边上的攻击对在e
处观察到的时间过程值具有最大影响。我们可以想象这是一个运输网络,节点上的值反映了到达位置/节点的产品数量。货物从源节点b
运送到目标节点e
。观察到的是节点受到攻击后节点值的变化,而没有观察到边缘值。
请找到用于攻击边缘的代码
import networkx as nx
import matplotlib.pyplot as plt
def attack(G):
print(G.edges())
for i,edge in enumerate(G.edges()):
no_attack = [(6,9),(3,16)]
if edge not in no_attack:
data = {}
print(f'attacking edge {edge}')
H = G.copy()
# attack an edge
H.remove_edges_from(ebunch=[edge])
n = len(G.nodes)
retain_node_ids = [9,3]
H.add_edges_from([(u,v) for u in retain_node_ids for v in (n+1,n+2)])
# remove nodes with degree < 2
H = nx.k_core(H,k=2)
H.remove_nodes_from([n + 1,n + 2])
# graph_utils_py.draw_graph3d(H,fig=2,show=True)
# H = nx.convert_node_labels_to_integers(H,first_label=1,ordering='default',label_attribute=None)
# delete connected nodes and edges
diff_nodes = set(G.nodes()).difference(H.nodes())
diff_edges = {e for e in G.edges() for n in diff_nodes if n in e}
print(f"deleting connected nodes {diff_nodes} ...")
print(f"deleting connected edges {diff_edges} ...")
data['diff_nodes'] = list(diff_nodes)
data['diff_edges'] = list(diff_edges)
data['edge'] = edge
if __name__ == '__main__':
n = 20
G = nx.gnm_random_graph(n=20,m=30,seed=1)
# nx.draw(G,with_labels=True)
# plt.show()
retain_node_ids = [11,4]
G.add_edges_from([(u,v) for u in retain_node_ids for v in (n,n + 1)])
G = nx.k_core(G,k=2)
G.remove_nodes_from([n,n + 1])
# nx.draw(G,with_labels=True)
# plt.show()
G = nx.convert_node_labels_to_integers(G,label_attribute=None)
nx.draw(G,with_labels=True)
plt.show()
attack(G)
EDIT2: 下面发布的答案建议通过改变不透明度并设置不同的配色方案来可视化边缘攻击。不幸的是,这没有帮助。必须为每种攻击创建不同的映像。我还在寻找其他建议。
我正在寻找类似以下的交互式图形。
一个人可以单击被攻击的边缘,LHS图将显示在目标节点上进行的观察。虚线是由于攻击给定边缘(存储在变量diff_edges
中)而受影响的边缘(存储在代码中的变量edge
中)。
如果在攻击链接后受影响的边缘存在重叠,我们可以将其显示为具有相应颜色映射的多行。交互式图形将帮助用户选择边缘攻击,以比较节点e处的观察结果。可以通过更改不透明度/线条样式/颜色来显示被侵蚀的边缘。
EDIT4:下面发布的答案会有所帮助。但是当受影响的边缘重叠时会出现问题。
例如, 攻击(H,(6,4),color ='red') Attack(H,(5,4),color ='yellow')
给予
颜色重叠,很难看到。如果我们可以将受影响的边缘彼此相邻且不重叠地绘制,如上面在edit3中发布的图像所示,那将是很好的。
解决方法
您可以首先删除受攻击的边缘,看看它是否使另一个相邻节点退役(受撞击的边缘),然后在找到右边缘后,使用特定于该攻击的颜色绘制它们。在这里,我以实心样式绘制了主要攻击,以虚线形式绘制了受影响的攻击。
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([('In',1),(5,'Out')]) # adding input/output nodes
pos = nx.spring_layout(H,iterations=400) # find good positions for nodes
edges = []
impacted_edges = []
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,color)
elif G.degree[edge[1]] == 1:
neighbor = [n for n in G.neighbors(edge[1])][0]
impacted_edge = (edge[1],color)
else:
impacted_edge = None
if impacted_edge:
impacted_edges.append(impacted_edge)
edges.append((edge[0],edge[1],color))
nx.draw_networkx_edges(
H,edgelist=[edge],pos=pos,edge_color=color,style='solid',label=f'Attack {edge[0]}-{edge[1]}',width=4
)
G.add_edge(*edge)
# attack some edges
attack(H,(6,4),color='red')
attack(H,(3,6),color='blue')
attack(H,(1,2),color='green')
attack(H,color='purple')
ax = plt.gca()
for edge in impacted_edges:
ax.annotate('',xy=pos[edge[0]],xytext=pos[edge[1]],zorder=1,arrowprops=dict(
color=edge[2],arrowstyle='-',connectionstyle='arc3,rad=0.2',lw=4,linestyle='--'
)
)
H.remove_edges_from([(e[0],e[1]) for e in impacted_edges])
H.remove_edges_from([(e[0],e[1]) for e in edges])
nx.draw(H,pos,node_size=700,with_labels=True,node_color='gray',edge_color='gray')
plt.legend()
plt.show()
希望您能在此答案中找到想要的。
,解决方案
在删除节点之前,将箭头添加到指向节点e
的边缘,将要删除的节点和边缘先变绿,然后变红,然后重复。还可以结合使用Alpha来表示最小-最大距离以及在图形修改时它们如何变化。
参考
NetworkX有向图示例:https://networkx.github.io/documentation/stable/auto_examples/drawing/plot_directed.html
NetworkX draw_networkx_edges参数(包括箭头,颜色和字母):https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw_networkx_edges.html
,需要Sankey Chart帮助吗?
sankey图是一种可视化视图,用于描述从一组值到另一组值的流程。下面的摘录来自Google图表,以图表流可视化的外观为例。
<html>
<body>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="sankey_multiple" style="width: 900px; height: 300px;"></div>
<script type="text/javascript">
google.charts.load("current",{packages:["sankey"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string','From');
data.addColumn('string','To');
data.addColumn('number','Weight');
data.addRows([
[ 'Brazil','Portugal',5 ],[ 'Brazil','France',1 ],'Spain','England',[ 'Canada',[ 'Mexico',[ 'USA',[ 'Portugal','Angola',2 ],'Senegal','Morocco','South Africa',3 ],[ 'France','Mali',[ 'Spain',[ 'England',7 ],[ 'South Africa','China','India','Japan',[ 'Angola',[ 'Senegal',[ 'Mali',[ 'Morocco',3 ]
]);
// Set chart options
var options = {
width: 600,};
// Instantiate and draw our chart,passing in some options.
var chart = new google.visualization.Sankey(document.getElementById('sankey_multiple'));
chart.draw(data,options);
}
</script>
</body>
</html>
如果您正在寻找python库,请查看Sankey diagrams in Plotly