Reputation: 3055
I have three types of nodes (dynmanicallly drawn hundred or thousands of nodes)
1- Animals 2- Trees 3- Humans
I am reading values from JSON file and dynamically nodes are created with unknown values.
I want to color them by their type. so I assigned a nodetype
property to identify.
Here is my node code for nodes.
G.add_node(HumanID, nodetype="red", UserName=userName)
G.add_node(TreeID, nodetype="green", BranchName=branchName)
G.add_node(AnimalID, nodetype="blue", AName=aName)
and to get the values
colors = set(nx.get_node_attributes(G,'nodetype').values())
print(colors)
output: {'green', 'red', 'blue'}
I know this is not right but I want something like this
nx.draw(G, node_color= colors)
so it should draw nodes with 3 different colors. I tried multiple ways to do so but since I am new with Networkx
and Matplotlib
so no success.
Upvotes: 2
Views: 2185
Reputation: 1852
When coloring graphs using nx.draw
it is key to keep the order of colors
the same as the nodes order.
So using a set won't do since these are unordered and do not allow duplicate values.
Instead what you want is, from the nx.draw_networkx
documentation:
node_color (color or array of colors (default=’#1f78b4’)) – Node color. Can be a single color or a sequence of colors with the same length as nodelist. Color can be string, or rgb (or rgba) tuple of floats from 0-1. If numeric values are specified they will be mapped to colors using the cmap and vmin,vmax parameters. See matplotlib.scatter for more details.
So if we consider a list, we can obtain colors
like this:
colors = [u[1] for u in G.nodes(data="nodetype")]
G=nx.Graph()
G.add_node(1, nodetype="red")
G.add_node(2, nodetype="blue")
G.add_node(3, nodetype="green")
G.add_node(4, nodetype="red")
G.add_edge(1, 3)
G.add_edge(2, 4)
G.add_edge(2, 3)
colors = [u[1] for u in G.nodes(data="nodetype")]
nx.draw(G, with_labels =True, node_color = colors)
EDIT:
Adding a node with nodetype="not_a_color"
:
G.add_node(4, nodetype="not_a_color")
colors = [u[1] for u in G.nodes(data="nodetype")]
nx.draw(G, with_labels =True, node_color = colors)
This gives the same error that you're getting:
ValueError: 'c' argument must be a color, a sequence of colors, or a sequence of numbers, not ['red', 'blue', 'green', 'not_a_color']
Of course that if you have a long list it is more difficult to check.
Try running the following, to check if there is a color that is neither "red"
,"green"
or "blue"
colors = [u[1] for u in G.nodes(data="nodetype")]
not_colors = [c for c in colors if c not in ("red", "green", "blue")]
if not_colors:
print("TEST FAILED:", not_colors)
If you have None
in any of your node's node_type
attribute, this will print those nodes in black:
#(change *colors* to):
colors = []
for u in G.nodes(data="nodetype"):
if u[1] in ("red", "green", "blue"):
colors.append(u[1])
elif u[1] == None:
colors.append("black")
else:
#do something?
print("ERROR: Should be red, green, blue or None")
Upvotes: 3