igraph-help
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [igraph] Simple syntax questions


From: Tamas Nepusz
Subject: Re: [igraph] Simple syntax questions
Date: Mon, 13 Apr 2009 20:14:10 +0100

Wondering if I could get an example. :-) I've been struggling to figure it out. Similar to http://igraph.sourceforge.net/igraphbook/igraphbook-creating.html#id2569368 but in Python.
Maybe you'll find the following page useful (it's fairly incomplete, but good for a start) if you are using igraph from Python:

http://www.cs.rhul.ac.uk/home/tamas/development/igraph/tutorial/tutorial.html

It seems igraph wants you to tell how many nodes you have before you can create an edge. Is this correct?
Yes, this is true. The reason is that igraph is a library written primarily in C and the usage of C imposes somewhat stricter rules on what can be done and what can't be done. One of the limitations is that edges and vertices are identified by integers starting from zero -- if I remember correctly, NetworkX is happy with arbitrary Python objects as nodes and edges.

I'm pulling from a database and I have a loop ready to go that says "x" (cat xyz, color blue) is related to "y" (cat abc, color red), next record, "y" is related to "z". It all seems simple, but I can't figure out how to make it happen.
In general, you need to construct a mapping (a Python dict) that maps these string identifiers to non-negative integers. The way you do it is absolutely up to you. I usually use a small helper class that simulates a Python dict but automatically assigns new IDs to new vertices. The helper class is as follows:

http://snipplr.com/view/13190/unique-id-sequence-class/

Using this helper class, you can do something like this:

names_to_idxs = UniqueIdGenerator()
edge_list = []
for row in my_data_source:
    v1, v2 = names_to_idxs[row["source"]], names_to_idxs[row["target"]]
    edge_list.append((v1, v2))
g = Graph(len(names_to_idxs), edge_list)

Note that I create the graph after I have read my data source completely. The reason is that the more code you manage to push down into the C core of igraph, the faster your code will be, and the code above constructs the graph in one single pass in the C layer, which is much faster than constructing the graph iteratively using add_vertices and add_edges (which traverses many times back and forth between the Python and the C layer). However, if you cannot do that for some reason, you can do this:

names_to_idxs = UniqueIdGenerator()
edge_list = []
g = Graph(0)
for row in my_data_source:
    v1, v2 = names_to_idxs[row["source"]], names_to_idxs[row["target"]]
    if max(v1, v2) >= g.vcount():
        g.add_vertices(max(v1, v2) - g.vcount() + 1)
    g.add_edges([(v1, v2)])

I also want to be able to say that x is "red", y is "blue" and in category "xyz". I want to tell it that the label and color of the edge between "y" and "z" is "this" and "that".
This can be done with igraph as well, using vertex and edge attributes; however, you will have to remember that you have to refer to vertices and edges by their numeric indices instead of their names. So, to say that vertex 0 is "red", you can do as follows:

g.vs[0]["color"] = "red"

g.vs acts as a list containing all the vertices. Indexing into g.vs gives you a Vertex object that acts as a Python dictionary. Similarly. g.es acts as a list containing all the edges and indexing into g.es gives you an Edge object:

g.es[0]["weight"] = 2.0

It is a common task to look up vertices by names, though. You can assign all the names to a "name" vertex attribute and then search for vertices using names:

names = ["A", "B", "C", "D", "E"]
g.vs["name"] = names # assuming that you have five vertices

At this point, g.vs.select(name="B") gives you all the vertices in a list-like object whose name attribute equals "B", so you can do the following:

my_node = g.vs.select(name="B")
my_node["color"] = "blue"

Hope this helps.

--
Tamas





reply via email to

[Prev in Thread] Current Thread [Next in Thread]