Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing weighted graph from adjacency matrix with edge labels

This is an adjacency matrix for a weighted graph, such that the element ai,j is the weight of the directed edge from node i to node j.

A = [
    [0, 1,  0,  .8, 0],
    [0, 0,  .4, 0,  .3],
    [0, 0,  0,  0,  0],
    [0, 0,  .6, 0,  .7],
    [0, 0,  0,  .2, 0]]

My main aim is to generate an illustration of that graph.

I can generate a graph in networkx like this:

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

G = nx.from_numpy_matrix(np.matrix(A), create_using=nx.DiGraph)
nx.draw(G)
plt.show()

But I cannot see the weights. I'm also not super happy with the image, it isn't publication ready. Does anyone have a good way to do this?

like image 868
chasmani Avatar asked Jan 26 '23 04:01

chasmani


2 Answers

You need to specify that you want to draw the edge labels. For that you have to call networkx.drawing.nx_pylab.draw_networkx_edge_labels.

That has an argument pos, a dictionary with nodes as keys and positions as values. It is important you use the same layout for the nodes and labels, or else they will not align!

An easy way is to let networkx handle the layout, for example with spring_layout.

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

A = [
    [0, 1,  0,  .8, 0],
    [0, 0,  .4, 0,  .3],
    [0, 0,  0,  0,  0],
    [0, 0,  .6, 0,  .7],
    [0, 0,  0,  .2, 0]]

G = nx.from_numpy_matrix(np.matrix(A), create_using=nx.DiGraph)
layout = nx.spring_layout(G)
nx.draw(G, layout)
nx.draw_networkx_edge_labels(G, pos=layout)
plt.show()

Example:

Example visualization with edge labels

Note that spring_layout uses the Fruchterman-Reingold force-directed algorithm which is non-deterministic, so your graph will almost certainly not look the same. However generally it produces good looking results so that should not be a major issue.

Documentation: networkx.drawing.layout.spring_layout, which does unfortunately not mention that it is non-deterministic.

UPDATE:

To have the labels be only the weights (and not a dictionary):

labels = nx.get_edge_attributes(G, "weight")
nx.draw_networkx_edge_labels(G, pos=layout, edge_labels=labels)
like image 175
Lomtrur Avatar answered Jan 31 '23 22:01

Lomtrur


import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

A = [
    [0, 1,  0,  .8, 0],
    [0, 0,  .4, 0,  .3],
    [0, 0,  0,  0,  0],
    [0, 0,  .6, 0,  .7],
    [0, 0,  0,  .2, 0]]

G = nx.from_numpy_matrix(np.matrix(A), create_using=nx.DiGraph)
layout = nx.spring_layout(G)
nx.draw(G, layout, node_size=1000, with_labels=True, font_weight='bold',    font_size=15)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos=layout,edge_labels=labels)
plt.show()
like image 33
maggie2000 Avatar answered Jan 31 '23 21:01

maggie2000