Reputation: 45
I am working with networkx in Python. I am facing an issue where I want to give different weightage to the different edges with same edge length for all.
Although with this code, with different weightage to edges, the length is also changing, which is undesirable.
I need some help with it.
Thanks in advance.
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()
Upvotes: 2
Views: 1179
Reputation: 80329
Default, a spring layout is used to layout the nodes. This often is the most pleasing. Also default, the spring layout uses the 'weight' attribute of the edges for their length. The heavier, the closer together. However, you can add your own attributes and tell spring_layout to use those. I named it 'draw_weight', but any name will do. You can also put it to None, which weights every edge equally (pos=nx.spring_layout(G, weight=None)
).
You can also experiment with other layout algorithms as mentioned in the documentation to replace the default 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()
Note that the edge lengths are never exactly equal, because the spring_layout tries to combine two strategies: to have nodes nicely separated and edge lengths close to the desired ones. For this example, the shell_layout would also look nice, but probably the idea is to have more complicated graphs. Some experimentation will be required.
Upvotes: 1