网络图中如何具有不同的边缘权重但边缘长度相同?

时间:2019-11-15 16:38:52

标签: python networkx

我正在Python中使用networkx。我面临一个问题,我想对所有具有相同边缘长度的不同边缘赋予不同的权重。

尽管使用此代码,边的权重不同,但长度也在变化,这是不希望的。

我需要一些帮助。

先谢谢了。

import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl

df = pd.DataFrame({'from': ['1', '2', '3', '4', '4', '4'], 'to': ['2', '3', '4', '5', '6', '7'], 'value': ['0.5', '0', '0', '0', '0', '0']})
df['value'] = pd.Categorical(df['value'])
df['value'].cat.codes


G = nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph())

cmap = plt.cm.cool
vmax = float(max(df['value']))
vmin = float(min(df['value']))
norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)

G = nx.Graph()
G.add_edge(1, 2,  weight=5)
G.add_edge(2, 3,  weight=0.5)
G.add_edge(3, 4,  weight=0.5)
G.add_edge(4, 5,  weight=0.5)
G.add_edge(4, 6,  weight=0.5)
G.add_edge(4, 7,  weight=0.5)
edges = G.edges()
weights = [G[u][v]['weight'] for u,v in edges]

nc = nx.draw_networkx(G, with_labels=True, node_color='yellow', node_size=700, edge_color=df['value'].cat.codes, width=weights, edge_cmap=cmap, font_size=10, font_color='black', font_weight='bold')

sm = plt.cm.ScalarMappable(cmap=cmap, norm=mpl.colors.Normalize(vmin = vmin, vmax = vmax))
sm._A = []
plt.colorbar(sm)
plt.axis('off')

plt.show()

resulting plot

1 个答案:

答案 0 :(得分:1)

默认情况下,使用弹簧布局来布局节点。这通常是最令人愉快的。同样默认,弹簧布局使用边缘的'weight'属性指定其长度。 较重,距离越近。但是,您可以添加自己的属性,并告诉spring_layout使用这些属性。我将其命名为“ draw_weight”,但是任何名称都可以。您还可以将其设置为“无”,这将平均加权每个边缘(pos=nx.spring_layout(G, weight=None))。

您还可以尝试使用the documentation中提到的其他布局算法来替换默认的spring_layout。

import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib as mpl

df = pd.DataFrame({'from': ['1', '2', '3', '4', '4', '4'], 'to': ['2', '3', '4', '5', '6', '7'], 'value': ['0.5', '0', '0', '0', '0', '0']})
df['value'] = pd.Categorical(df['value'])
df['value'].cat.codes


G = nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph())

cmap = plt.cm.cool
vmax = float(max(df['value']))
vmin = float(min(df['value']))
norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)

G = nx.Graph()
G.add_edge(1, 2,  weight=5,    draw_weight=1)
G.add_edge(2, 3,  weight=0.5,  draw_weight=1)
G.add_edge(3, 4,  weight=0.5,  draw_weight=1)
G.add_edge(4, 5,  weight=0.5,  draw_weight=1)
G.add_edge(4, 6,  weight=0.5,  draw_weight=1)
G.add_edge(4, 7,  weight=0.5,  draw_weight=1)
edges = G.edges()
weights = [G[u][v]['weight'] for u,v in edges]

nc = nx.draw_networkx(G, pos=nx.spring_layout(G, weight='draw_weight'),  with_labels=True, node_color='yellow', node_size=700, edge_color=df['value'].cat.codes, width=weights, edge_cmap=cmap, font_size=10, font_color='black', font_weight='bold')

sm = plt.cm.ScalarMappable(cmap=cmap, norm=mpl.colors.Normalize(vmin = vmin, vmax = vmax))
sm._A = []
plt.colorbar(sm)
plt.axis('off')

plt.show()

The resulting graph layout

请注意,边的长度永远不会完全相等,因为spring_layout尝试结合两种策略:将节点很好地分开并且边的长度接近所需的长度。对于此示例,shell_layout看起来也不错,但可能的想法是拥有更复杂的图形。需要一些实验。