Networkx - Change Color/Width According to Edge Attributes - Inconsistent Result

Change Edge color in NetworkX Graph depending on what edges has been visisted by Dijkstras algorithm

Try adding edge_color to nx.draw()

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()

nodes = G.nodes()

position = nx.spring_layout(G)
color = {"Mr. Hi": "#3DA3F5", "Officer": "#E0D91B"}
dijkstra_route = nx.dijkstra_path(G, 24, 16)

colors = ["red" if n in dijkstra_route else color[G.nodes[n]["club"]] for n in nodes]

dijkstra_edges = []
for index in range(0, len(dijkstra_route) - 1):
edge = (dijkstra_route[index], dijkstra_route[index + 1])
dijkstra_edges.append(edge)

edge_colors = ["red" if edge in dijkstra_edges else "black" for edge in G.edges()]

nx.draw(G, position, node_color=colors, edge_color=edge_colors, with_labels=True)
plt.show()

shows this, which is close to what you want, although I can't figure out why edge (31,0) isn't colored

Edge color based on weights in Networkx

Try this:

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable

N = 1

def pos():
x, y = 1, N + 3 - 1
for _ in range(2 * N * (N + 1)):
yield (x, y)
y -= (x + 2) // (N + 3)
x = (x + 2) % (N + 3)

G = nx.Graph()
it_pos = pos()
for u in range(2 * N * (N + 1)):
G.add_node(u + 1, pos=next(it_pos))
if u % (2 * N + 1) < N:
for v in (u - 2 * N - 1, u - N - 1, u - N):
if G.has_node(v + 1):
G.add_edge(u + 1, v + 1)
elif u % (2 * N + 1) == N:
G.add_edge(u + 1, u - N + 1)
elif u % (2 * N + 1) < 2 * N:
for v in (u - 1, u - N - 1, u - N):
G.add_edge(u + 1, v + 1)
else:
for v in (u - 1, u - N - 1):
G.add_edge(u + 1, v + 1)

nx.draw(G, nx.get_node_attributes(G, 'pos'), with_labels=True, font_weight='bold')
Edges=np.array([[1,2],[1,3],[1,4]])
Weights=np.array([[1.7],[2.9],[8.6]])
flat_weights = Weights.flatten()
weights_normalized = [x / max(flat_weights) for x in flat_weights]
edge_weight_map = dict(zip([tuple(e) for e in Edges.tolist()],weights_normalized))
my_cmap = plt.cm.get_cmap('Oranges')
colors = my_cmap([edge_weight_map.get(tuple(e), 0) for e in Edges.tolist()])
pos = nx.get_node_attributes(G, 'pos')
sm = ScalarMappable(cmap=my_cmap, norm=plt.Normalize(0,max(flat_weights)))
nx.draw_networkx_edges(G, pos, edge_color=colors,
edgelist=[tuple(e) for e in Edges.tolist()],
width=5);
plt.colorbar(sm)

Output:

Sample Image

python networkx - how to draw graph with varying edge width

Not sure what exactly is happening when one calls nx.draw_networkx_edges() However according to the docs one can explicitly provide a edgelist argument. Thus providing the edgelist in the same order as weights fixed the issue:


G = nx.Graph()
dx = 4 # spacing
# create nodes
for nidx, (ridx, cidx) in enumerate(product(range(4), range(5))):
#print(ridx,cidx)
G.add_node(nidx, pos=(dx*cidx, -dx*ridx) )

# create edges
nedges = 31
for gidx, w in zip(edge_index, weights):
#print(gidx, w)
G.add_edge(*gidx, weight=w)


pos=nx.get_node_attributes(G,'pos')
labels = {k:f"{v:.3f}" for k, v in nx.get_edge_attributes(G, 'weight').items()}
nx.draw(G, pos)
nx.draw_networkx_labels(G, pos=pos, font_color='w')
#######################################################################
nx.draw_networkx_edges(G, pos, edgelist=edge_index, width=10*weights) # <--- changed this line
#######################################################################
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
plt.show()

Sample Image

Access attributes of a Multigraph in NetworkX

Changing the line causing the error to

colors = [print(G[u][v]) for u,v in edges]

We can see what you are actually looking at is:

{0: {'color': 'r'}}
{0: {'color': 'b'}}
{0: {'color': 'g'}}

I assume networkx is storing which graph it is on as the key, so you just need to access key [0] first, like this:

colors = [G[u][v][0]["color"] for u,v in edges]

This access pattern is somewhat documented on https://networkx.github.io/documentation/networkx-1.9.1/reference/classes.multigraph.html in the edges section.



Related Topics



Leave a reply



Submit