如何解决具有权重和类型相关节点和边的网络图 完整代码如下:
我有以下从 .xlsx 文件导入的简化数据库
df = pd.DataFrame({ 'from':['A','A','B','C','C'],'to':['B','C,'B'],'weight':['10','5','25','2','4','8'],'type':['typeA','typeA','typeB','typeC','typeC]})
与上面相同的数据库,为了清楚起见:
from: A A B B C C
to: B C A C A B
weight: 10 5 25 15 2 4
type: typeA typeA typeB typeB typeC typeC
我想创建一个具有特征的网络图表
- 节点
- 不同的颜色取决于类型
- 根据重量增加尺寸,例如节点 A 大小与 (10 +5) 成正比
- 边缘
- 不同的颜色取决于类型
- 根据单个重量增加宽度,例如边AB宽度与10成正比,边AC宽度与5成正比
到目前为止,我只能制作未考虑此标准的网络图
G=nx.nx.from_pandas_edgelist(df,'from','to','type',create_using=nx.Graph())
nx.draw(G,with_labels=True,node_size=1500,node_color="skyblue",pos=nx.fruchterman_reingold_layout(G))
如何使代码动态化并指定它以确保它符合标准,例如添加新数据或更改权重?
解决方法
要从 pandas 边列表中动态获取图形,您可以使用 pandas itertuples
。
以下是它的基本工作原理:
for row in df.itertuples():
n = row[0] # 'from' is a reserved word so 'row.from' returns Syntax Error
u = row.to
w = row.weight
t = row.type
G.add_node(n,weight = w,type_ = t)
G.add_node(u,type_ = t)
G.add_edge(n,u,type_ = t) # weight of edge
现在让我们添加一些打印件让您知道数据何时发生变化:
for row in df.itertuples():
u = row[1] # 'from' is a reserved word so 'row.from' returns Syntax Error
v = row.to
w = row.weight
t = row.type
if u in G:
new_data = {'weight':w,'type_':t}
if G.nodes(data=True)[u] != new_data:
print("Node {} data update: {} {}".format(u,G.nodes(data=True)[u],new_data))
G.nodes()[u]["weight"] = w
G.nodes()[u]["type_"] = t
else:
G.add_node(u,type_ = t)
if v in G:
new_data = {'weight':w,'type_':t}
if G.nodes(data=True)[v] != new_data:
print("Node {} data update: {} {}".format(v,G.nodes(data=True)[v],new_data))
G.nodes()[v]["weight"] = w
G.nodes()[v]["type_"] = t
else:
G.add_node(v,type_ = t)
G.add_edge(u,v,type_ = t)
现在,按照你假装的方式绘制网络:
每种类型都有一种颜色:
type_to_color = {
"typeA": "blue","typeB": "red","typeC": "green"
}
节点颜色和权重可以这样获得:
n_colors = [type_to_color[u[1]] for u in g.nodes(data="type_")] # u[1] must be either typeA,typeB,typeC
n_sizes = [int(u[1]) for u in g.nodes(data="weight")] # you may want to scale these a little e.g n_sizes = [int(u[1])*10 for u in g.nodes(data="weight")]
可以像这样获得边缘颜色和权重:
edge_widths = [int(g[u][v]['weight']) for u,v in g.edges()]
edge_colors = [type_to_color[g[u][v]['type_']] for u,v in g.edges()]
接下来,像这样绘制网络:
nx.draw(g,with_labels = True,node_color = n_colors,edge_color=edge_colors,node_size=n_sizes,width=edge_widths)
完整代码如下:
def get_graph_from_pandas(df,v = False):
G = nx.Graph()
for row in df.itertuples():
u = row[1] # 'from' is a reserved word so 'row.from' returns Syntax Error
v = row.to
w = row.weight
t = row.type
if u in G:
new_data = {'weight':w,'type_':t}
if G.nodes(data=True)[u] != new_data:
print("Node {} data update: {} {}".format(u,new_data))
G.nodes()[u]["weight"] = w
G.nodes()[u]["type_"] = t
else:
G.add_node(u,type_ = t)
if v in G:
new_data = {'weight':w,'type_':t}
if G.nodes(data=True)[v] != new_data:
print("Node {} data update: {} {}".format(v,new_data))
G.nodes()[v]["weight"] = w
G.nodes()[v]["type_"] = t
else:
G.add_node(v,type_ = t)
G.add_edge(u,type_ = t)
return G
def draw_graph(g):
type_to_color = {
"typeA": "blue","typeC": "green",None:"black"
}
print([u[1] for u in g.nodes(data="type_")])
n_colors = [type_to_color[u[1]] for u in g.nodes(data="type_")] # u[1] must be either typeA,typeC
n_sizes = [int(u[1]) for u in g.nodes(data="weight")] # you may want to scale these a little e.g n_sizes = [int(u[1])*10 for u in g.nodes(data="weight")]
print(n_sizes)
edge_widths = [int(g[u][v]['weight']) for u,v in g.edges()] # you may want to scale these a little e.g edge_widths = [int(g[u][v]['weight'])*0.1 for u,v in g.edges()]
edge_colors = [type_to_color[g[u][v]['type_']] for u,v in g.edges()]
nx.draw(g,width=edge_widths)
return g
有任何问题,请留言;)
,这是 different example 的链接
这是您的示例:
import pandas as pd
import networkx as nx
df = pd.DataFrame({'from':['A','A','B','C','C'],'to':['B','B'],'weight':['10','5','25','2','4','8'],'type':['typeA','typeA','typeB','typeC','typeC']})
df['weight'] = df['weight'].astype(int)
nodeweight = (df.groupby('from')['weight'].sum()*10).to_dict()
G=nx.nx.from_pandas_edgelist(df,'from','to',['type','weight'],create_using=nx.Graph())
edgeweights = [i[2]['weight'] for i in G.edges(data=True)]
nodelist = list(G.nodes)
edgelabels = {(i[0],i[1]):f'{i[0]}{i[1]}' for i in G.edges()}
nodesize = [nodeweight[i] for i in nodelist]
colorlist=[*'rbg']
pos = nx.fruchterman_reingold_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=nodesize,node_color=colorlist,labels=True);
nx.draw_networkx_edges(G,width=edgeweights);
nx.draw_networkx_labels(G,font_size=10,font_family='sans-serif',font_color='white');
nx.draw_networkx_edge_labels(G,edge_labels=edgelabels,font_color='red');
输出:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。