Reputation: 1
I am a complete noob in python and am trying to make a graph with nodes labelled as $v_1$, up to $v_n$ and edges labelled as $e_1$ up to $e_n$.
I have input the attribute label in nodes called 'label' and used it to store the labels $v_i$s. Next I am trying to read the label attributes into a dictionary to pass it to nx.draw for vertex labels.
The code is as follows.
import networkx as nx
import matplotlib.pyplot as plt
def power_graph(g, power_k):
nx.set_edge_attributes(g, values='b', name='color')
number_of_nodes = nx.number_of_nodes(g)
spl = dict(nx.all_pairs_shortest_path_length(g))
for i in range(number_of_nodes):
for j in range(i + 1, number_of_nodes):
if spl[i][j] == power_k:
g.add_edge(i, j, color='r')
return g
def make_cycle(n):
G=nx.Graph()
for i in range(n-1):
G.add_node(i, label=str(r"$v_{%d}$" % i))
for i in range(n-1):
G.add_edge(i, i+1, color='b', label=r"$e_{%d}$" % i)
G.add_edge(0, n-1, color='b')
return G
# Take input from the user
num_vertex = int(input("Enter the number of vertices: "))
power = int(input("Enter the power (distance between connected vertices): "))
g=make_cycle(num_vertex)
pow_g = power_graph(g, power)
# Draw the graph
pos = nx.circular_layout(pow_g)
colors = nx.get_edge_attributes(pow_g, 'color').values()
labels = dict(nx.get_edge_attributes(g, 'label').values())
plt.title(f"Cycle Graph with {num_vertex} Vertices (Power = {power})") # Write the description
nx.draw(pow_g, pos, edge_color=colors, node_color='lightgreen', labels=label, with_labels=True, node_size=500, font_size=10)
plt.show()
I am getting this error message
Traceback (most recent call last):
File "C:\Users\murad\PycharmProjects\Metric Dimension\Cycle Power Graph.py", line 40, in <module>
labels = dict(nx.get_edge_attributes(g, 'label').values())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: dictionary update sequence element #0 has length 7; 2 is required
I know that the problem is when I am trying to change the label attribute to dictionary, that it should be a key and a label dictionary of length 2. I still can not understand the nature of the problem. If someone can kindly elaborate on what i am doing wrong.
Thanks a lot for your patience and time and since it is my first time asking such a question, kindly oversee any mistakes i made.
Upvotes: 0
Views: 35
Reputation: 1
There are two distinct problems with your approach. First, you are trying to convert a list of strings to a dictionary without supplying keys. Secondly, you are mixing up node and edge labels when calling nx.draw
.
dict
conversionYou are trying to convert a list of strings (i.e. nx.get_edge_attributes(g, 'label').values()
) to a dictionary. The dict()
constructor however expects a list of tuples of length 2, a key and the actual values. The return value of nx.get_edge_attributes
is already a dictionary and you can simply take that as your edge labels:
labels = nx.get_edge_attributes(g, 'label')
The reason you still need to convert the colors
to a list by calling .values()
is that draw_networkx
expects an array as an input not a dictionary.
In the following line are supplying edge labels where networkx is expecting node labels:
nx.draw(pow_g, pos, edge_color=colors, node_color='lightgreen', labels=labels, with_labels=True, node_size=500, font_size=10)
To draw the actual edge labels, you have to use draw_networkx_edge_labels
:
nx.draw(pow_g, pos, edge_color=colors, node_color='lightgreen', with_labels=True, node_size=500, font_size=10)
nx.draw_networkx_edge_labels(pow_g, pos, edge_labels=labels)
The updated code could look like this:
# Set graph size and power
num_vertex = 10
power = 2
# Create graph with the original functions
g=make_cycle(num_vertex)
pow_g = power_graph(g, power)
# Draw the graph
pos = nx.circular_layout(pow_g)
colors = nx.get_edge_attributes(pow_g, 'color').values()
labels = nx.get_edge_attributes(g, 'label')
plt.title(f"Cycle Graph with {num_vertex} Vertices (Power = {power})") # Write the description
nx.draw(pow_g, pos, edge_color=colors, node_color='lightgreen', with_labels=True, node_size=500, font_size=10)
nx.draw_networkx_edge_labels(pow_g, pos, edge_labels=labels)
plt.draw()
Upvotes: 0