Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

networkx: Draw text on edges

for my thesis I need to draw some probabilistic control flow graphs. i.e. control flow graphs with probabilities depicted on the edges.

I found graph-tool which seems quite useful, since it can use deep-copies of existing graphs and my graphs are quite similar.

So my question is, if there is a possibility to draw edge properties (or some strings) on/next to the edges? If it's not possible or highly complicated, is there a tool which is better to use in this case?

Edit: I need directed edges that can even create loops between 2 nodes and have different values. Is there a possibility for this too? So I can see both values? By now I can see the directed graph with a 2-directional edge, but there's only one value on it.

So e.g. in networkx (in reference to Hooked) it would look like:

G = nx.MultiDiGraph()
G.add_edge(0,1)
G.add_edge(1,0)
labels = {(0,1):'foo', (1,0):'bar'}

So that both 'foo' and 'bar' are visible and you can see which direction they are connected to.

But as networkx renders it, I get 1 bidirectional edge with 1 of the labels.

like image 230
Dominik G Avatar asked Dec 20 '12 14:12

Dominik G


2 Answers

You can draw text next to the edges with graph-tool using "edge_text" option of the graph_draw() function:

from graph_tool.all import *

g = Graph()
g.add_vertex(4)
label = g.new_edge_property("string")
e = g.add_edge(0, 1)
label[e] = "A"
e = g.add_edge(2, 3)
label[e] = "foo"
e = g.add_edge(3, 1)
label[e] = "bar"
e = g.add_edge(0, 3)
label[e] = "gnat"

graph_draw(g, edge_text=label, edge_font_size=40, edge_text_distance=20, edge_marker_size=40, output="output.png")

enter image description here

like image 144
Tiago Peixoto Avatar answered Nov 12 '22 06:11

Tiago Peixoto


import networkx as nx   

# Sample graph
G = nx.Graph()
G.add_edge(0,1)
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(1,3)

labels = {(0,1):'foo', (2,3):'bar'}

pos=nx.spring_layout(G)

nx.draw(G, pos)
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels,font_size=30)

import pylab as plt
plt.show()

enter image description here

EDIT: If you need multidigraphs with edge labels, I don't think you can do this completely within networkx. However you can do most of it in python and do the rendering and layout with another program:

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge(0,1, label='A')
G.add_edge(1,0, label='B')
G.add_edge(2,3, label='foo')
G.add_edge(3,1, label='bar')   
nx.write_dot(G, 'my_graph.dot')

I use graphviz to turn this into an image. On my Unix machine I run this from the command-line

dot my_graph.dot -T png > output.png

Which gives the desired output you are looking for. Note that graphviz has many ways to customize the visual appearance. The above example simply produces:

enter image description here

like image 36
Hooked Avatar answered Nov 12 '22 08:11

Hooked