Murad khan
Murad khan

Reputation: 1

Labeling Graph Vertices as $v_1$, $v_2$ and so on using networkx

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

Answers (1)

Livus
Livus

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.

1. Incorrect dict conversion

You 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.

2. Properly drawing edge labels

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)

Final solution

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

Plotted graph

Upvotes: 0

Related Questions