networkx: Assigning node colors based on weight when using bbox

Question:

I want to draw a graph with networx and render the nodes as boxes wide enough to contain each node’s name, colored according to its weight.

If I use the default shape, they are colored correctly, but when I use the bbox parameter facecolor, they all have the same color.

enter image description here

from pprint import pprint

import matplotlib.pyplot as plt
import networkx as nx
from networkx.drawing.nx_pydot import graphviz_layout

G = nx.Graph()
G.add_node((1, 4), weight=10/255)
G.add_node((7, 2), weight=130/255)
G.add_node((9, 7), weight=250/255)
node_labels = dict()
node_colors = []
for node, node_data in G.nodes.items():
    node_labels[node] = node
    node_colors.append(node_data['weight'])
pprint(node_labels)
pprint(node_colors)
fig, axs = plt.subplots(ncols=2)
plt.margins(0.0)
pos = graphviz_layout(G, prog='dot')
nx.draw(G, pos=pos, with_labels=True, labels=node_labels, node_color=node_colors, cmap=plt.cm.gray, ax=axs[0])
nx.draw(G, pos=pos, with_labels=True, labels=node_labels, node_color=node_colors, cmap=plt.cm.gray, ax=axs[1], bbox=dict(facecolor=node_colors, edgecolor='black', boxstyle='round,pad=0.2'))
fig.tight_layout()

plt.show()

Answers:

You can draw the labels individually. This way you can store them and acces them later. Use nx.draw_networkx_labels to draw and get them. Then you iterate over those (they are in order of the graph) and set the color of the indivudal boxes according to you desired output. Below is an example:

import matplotlib.pyplot as plt
import networkx as nx
from networkx.drawing.nx_pydot import graphviz_layout

G = nx.Graph()
G.add_node((1, 4), weight=10/255)
G.add_node((7, 2), weight=130/255)
G.add_node((9, 7), weight=250/255)
node_labels = dict()
node_colors = []
for node, node_data in G.nodes.items():
    node_labels[node] = node
    node_colors.append(node_data['weight'])


fig, axs = plt.subplots(nrows=2, figsize=(6,3))

pos = graphviz_layout(G, prog='dot')
nx.draw(G, pos=pos, with_labels=True, labels=node_labels, node_color=node_colors, cmap=plt.cm.gray, ax=axs[0])

axs[1].set_axis_off()
nx.draw_networkx_nodes(G, pos=pos, ax = axs[1], node_size=0)
labels = nx.draw_networkx_labels(G, pos=pos, ax = axs[1], labels=node_labels,
                            bbox=dict(edgecolor='black', boxstyle='round,pad=0.2'))

#iterate over the labels (key = label, value=matplotlib Text object)
for t, c in zip(labels.values(), node_colors):
    #manipulate indiviual text objects
    t.set_backgroundcolor(plt.cm.gray(c))

fig.tight_layout()

plt.show()

This yields:

enter image description here

Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.