如何反转Pyvis有向网络图箭头方向,使其指向红色节点?
问题:反转Pyvis有向网络图的箭头方向
我用Pyvis生成了一个效果出色的有向网络图,当前边的方向是从hash列指向input_prev_tx_hash列。我希望反转所有箭头的方向,让它们全部指向红色节点。请问Pyvis是否有内置函数实现该需求?或者有没有其他可行的方法?
我曾尝试使用NetworkX,但无法实现Pyvis那样美观的HTML可视化效果,因此希望保留Pyvis的可视化方式。
相关代码如下:
import pandas as pd import numpy as np import pyarrow.feather as feather from pyvis import network as net from IPython.core.display import display, HTML import networkx as nx from graph_based_clustering import ConnectedComponentsClustering import matplotlib.pyplot as plt from sklearn.cluster import KMeans import markov_clustering as mc from node2vec import Node2Vec df = pd.read_feather('block_100000') value= df[["input_prev_tx_hash","input_prev_value"]] value = value.drop_duplicates() value = value.dropna() def get_size(node): value_list = list() for i in node: v = value[value["input_prev_tx_hash"]== i]["input_prev_value"].item() v = v/1000000000 value_list.append(v) return value_list #edges edges = df[["hash", "input_prev_tx_hash"]].copy() edges = edges.dropna() edges = edges.drop_duplicates() edges.drop(edges[edges["hash"]=="0000000000000000000000000000000000000000000000000000000000000000"].index, inplace = True) edges.drop(edges[edges["input_prev_tx_hash"]=="0000000000000000000000000000000000000000000000000000000000000000"].index, inplace = True) print(edges) features = df[["hash"]].copy() features = features.drop_duplicates() features.drop(features[features["hash"]=="0000000000000000000000000000000000000000000000000000000000000000"].index, inplace = True) #features.sort_values(by=["1"]) nodes_1 = features["hash"].to_numpy() nodes_1 = nodes_1[4].split() edges_1 = edges[edges['hash'].isin(nodes_1)] nodes_2 = edges_1['input_prev_tx_hash'].to_numpy() edges_2 = edges[edges['hash'].isin(edges_1['input_prev_tx_hash'])] nodes_3 = edges_2['input_prev_tx_hash'].to_numpy() edges_3 = edges[edges['hash'].isin(edges_2['input_prev_tx_hash'])] nodes_4 = edges_3['input_prev_tx_hash'].to_numpy() edges_4 = edges[edges['hash'].isin(edges_3['input_prev_tx_hash'])] nodes_5 = edges_4['input_prev_tx_hash'].to_numpy() edges_5 = edges[edges['hash'].isin(edges_4['input_prev_tx_hash'])] nodes_6 = edges_5['input_prev_tx_hash'].to_numpy() edges_6 = edges[edges['hash'].isin(edges_5['input_prev_tx_hash'])] nodes_7 = edges_6['input_prev_tx_hash'].to_numpy() edges_7 = edges[edges['hash'].isin(edges_6['input_prev_tx_hash'])] nodes_8 = edges_7['input_prev_tx_hash'].to_numpy() edges_8 = edges[edges['hash'].isin(edges_7['input_prev_tx_hash'])] nodes_9 = edges_8['input_prev_tx_hash'].to_numpy() edges_9 = edges[edges['hash'].isin(edges_8['input_prev_tx_hash'])] nodes_10 = edges_9['input_prev_tx_hash'].to_numpy() edges_10 = edges[edges['hash'].isin(edges_9['input_prev_tx_hash'])] nodes_11 = edges_10['input_prev_tx_hash'].to_numpy() edges_11 = edges[edges['hash'].isin(edges_10['input_prev_tx_hash'])] nodes_12 = edges_11['input_prev_tx_hash'].to_numpy() edges_12 = edges[edges['hash'].isin(edges_11['input_prev_tx_hash'])] nodes_13 = edges_12['input_prev_tx_hash'].to_numpy() edges_13 = edges[edges['hash'].isin(edges_12['input_prev_tx_hash'])] nodes_14 = edges_13['input_prev_tx_hash'].to_numpy() edges_14 = edges[edges['hash'].isin(edges_13['input_prev_tx_hash'])] #nodes_1 = nodes_1.tolist() nodes_2 = nodes_2.tolist() nodes_3 = nodes_3.tolist() nodes_4 = nodes_4.tolist() nodes_5 = nodes_5.tolist() nodes_6 = nodes_6.tolist() nodes_7 = nodes_7.tolist() nodes_8 = nodes_8.tolist() nodes_9 = nodes_9.tolist() nodes_10 = nodes_10.tolist() nodes_11 = nodes_11.tolist() nodes_12 = nodes_12.tolist() nodes_13 = nodes_13.tolist() nodes_14 = nodes_14.tolist() edges_1 = edges_1.to_records(index=False).tolist() edges_2 = edges_2.to_records(index=False).tolist() edges_3 = edges_3.to_records(index=False).tolist() edges_4 = edges_4.to_records(index=False).tolist() edges_5 = edges_5.to_records(index=False).tolist() edges_6 = edges_6.to_records(index=False).tolist() edges_7 = edges_7.to_records(index=False).tolist() edges_8 = edges_8.to_records(index=False).tolist() edges_9 = edges_9.to_records(index=False).tolist() edges_10 = edges_10.to_records(index=False).tolist() edges_11 = edges_11.to_records(index=False).tolist() edges_12 = edges_12.to_records(index=False).tolist() edges_13 = edges_13.to_records(index=False).tolist() edges_14 = edges_14.to_records(index=False).tolist() g=net.Network(bgcolor='#222222', font_color='white', directed=True) # use 'directed=True' for arrows showing the direction of the edges g.add_nodes(nodes_1, color=['red']) g.add_nodes(nodes_2, size=get_size(nodes_2)) g.add_nodes(nodes_3, size=get_size(nodes_3)) g.add_nodes(nodes_4, size=get_size(nodes_4)) g.add_nodes(nodes_5, size=get_size(nodes_5)) g.add_nodes(nodes_6, size=get_size(nodes_6)) g.add_nodes(nodes_7, size=get_size(nodes_7)) g.add_nodes(nodes_8, size=get_size(nodes_8)) g.add_nodes(nodes_9, size=get_size(nodes_9)) g.add_nodes(nodes_10, size=get_size(nodes_10)) g.add_nodes(nodes_11, size=get_size(nodes_11)) g.add_nodes(nodes_12, size=get_size(nodes_12)) g.add_nodes(nodes_13, size=get_size(nodes_13)) g.add_nodes(nodes_14, size=get_size(nodes_14)) g.add_edges(edges_1) g.add_edges(edges_2) g.add_edges(edges_3) g.add_edges(edges_4) g.add_edges(edges_5) g.add_edges(edges_6) g.add_edges(edges_7) g.add_edges(edges_8) g.add_edges(edges_9) g.add_edges(edges_10) g.add_edges(edges_11) g.add_edges(edges_12) g.add_edges(edges_13) g.add_edges(edges_14) g.show("example.html")
解决方案
Pyvis目前没有内置的一键反转所有边方向的函数,但可以通过以下两种简单方法实现需求:
方法一:直接反转每条边的节点顺序
这是最直接的方式,只需要调整边的节点顺序即可:
方式1:修改原始边数据的列顺序
在生成边数据时,调换hash和input_prev_tx_hash的位置:
# 原代码:edges = df[["hash", "input_prev_tx_hash"]].copy() edges = df[["input_prev_tx_hash", "hash"]].copy()
后续生成的所有边列表(edges_1到edges_14)都会自动变成从input_prev_tx_hash指向hash的方向,也就是箭头全部指向红色节点。
方式2:反转已生成边列表的元组顺序
如果不想修改原始edges数据,可在转换边列表时逐个反转元组:
edges_1 = edges_1.to_records(index=False).tolist() edges_1 = [(dst, src) for src, dst in edges_1] # 反转每条边的方向
对edges_2到edges_14执行同样的反转操作即可。
方法二:借助NetworkX反转后导入Pyvis
若已使用NetworkX构建图,可先反转边方向再导入Pyvis:
# 用原边数据创建NetworkX有向图 nx_g = nx.DiGraph() nx_g.add_edges_from(edges.to_records(index=False).tolist()) # 反转所有边方向 reversed_nx_g = nx.reverse(nx_g) # 导入Pyvis并保留可视化样式 g = net.Network(bgcolor='#222222', font_color='white', directed=True) g.from_nx(reversed_nx_g) # 重新设置节点颜色、大小等属性 g.add_nodes(nodes_1, color=['red']) # ... 其他节点属性设置 g.show("example.html")
推荐使用方法一,操作简单且无需额外依赖转换,完全保留Pyvis的原生可视化效果。
内容的提问来源于stack exchange,提问作者ralphito
相关产品推荐
相关产品推荐

