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