Home > Software design >  networkx: Assigning node colors based on weight when using bbox
networkx: Assigning node colors based on weight when using bbox

Time:12-30

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()

CodePudding user response:

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

  • Related