Ask Your Question
0

plot digraph use adjacency matrix

asked 2013-02-06 00:47:34 +0100

tsang gravatar image

updated 2016-06-07 20:58:46 +0100

FrédéricC gravatar image

Hi everyone, I got a question here, and I have been trying to debug it for past week, still can't get it sorted out, can anyone please help me? Thanks heaps.

I have a file as my data (will paste at the bottom), basically the vertices are all binary strings with directed edges named "a" or "b", or "c". For example, if in my data, there is line says (0000, a, 1000), that means there is an edge from vertex 0000 to 1000 named a. Similarly, if I have (0000, b, 0000), means there is a self-loop from 0000 to it self named b. So there can be more than one self-loops sometimes.

Now I have written the function digraph as below:

def digraph(n, filename):
    f = open(filename, 'r')
    W = Words('01', length=n)
    S = [str(w) for w in W]
    M = zero_matrix(ZZ, 2^n)
    f.readline()
    for c in f:
        c = c[1:-2]
        s1, g, s2 = c.split(', ')
        i = S.index('word: ' + s1)
        j = S.index('word: ' + s2)
        M[i,j] = 1
    f.close()
    return DiGraph(M, vertex_labels=S, loops = True, implementation="c_graph")

So the idea should be pretty simple, create list of words with all binary strings length 4, then search where my data the words are allocated in the list, then assign value to 1 to the entries of my original zero matrix.

But I keep getting error message says change a copy of the matrix instead, I tried to make a copy(M), but still doesn't work, then it says something else like "need more than 1 value unpack" etc.

I really need a hand on this please, can anybody help me please? Also, I can't understand why it is exactly same code, but used to run very well on someone else's linux computer two months ago, and I didn't change anything but it just wouldn't run here and the error messages seem like syntax error.

Here are my data as below

(0000, a, 1000)
(0000, b, 0000)
(0000, c, 0000)
(0001, a, 1001)
(0001, b, 0001)
(0001, c, 0001)
(0010, a, 1010)
(0010, b, 0010)
(0010, c, 0010)
(0011, a, 1011)
(0011, b, 0011)
(0011, c, 0011)
(0100, a, 1110)
(0100, b, 0100)
(0100, c, 0100)
(0101, a, 1111)
(0101, b, 0101)
(0101, c, 0101)
(0110, a, 1100)
(0110, b, 0111)
(0110, c, 0111)
(0111, a, 1101)
(0111, b, 0110)
(0111, c, 0110)
(1000, a, 0000)
(1000, b, 1000)
(1000, c, 1100)
(1001, a, 0001)
(1001, b, 1001)
(1001, c, 1101)
(1010, a, 0010)
(1010, b, 1010)
(1010, c, 1111)
(1011, a, 0011)
(1011, b, 1011)
(1011, c, 1110)
(1100, a, 0110)
(1100, b, 1110)
(1100, c, 1000)
(1101, a, 0111)
(1101, b, 1111)
(1101, c, 1001)
(1110, a, 0100)
(1110, b, 1100)
(1110, c, 1011)
(1111, a, 0101)
(1111, b, 1101)
(1111, c, 1010)
edit retag flag offensive close merge delete

Comments

How is plotting relevant to this question?

fidbc gravatar imagefidbc ( 2013-02-06 07:50:51 +0100 )edit

5 Answers

Sort by » oldest newest most voted
1

answered 2013-02-06 07:49:29 +0100

fidbc gravatar image

Here are some comments about some things to watch out for in your code.

The lines

    i = S.index('word: ' + s1)
    j = S.index('word: ' + s2)

should not need the prefix 'word: ', since words in S don't contain such prefix by the way it is defined.

Line 6, f.readline(), might just be discarding the first line of your input.

When you set M[i,j]=1 you might lose track of multiple edges, maybe changing it to M[i,j] += 1 will do.

Also, I guess the labels a, b and c are relevant, so to preserve labels you can just add an edge between s1 and s2 with label g.

Perhaps the following version might do the job

def my_digraph(filename):
    f = open(filename, 'r')
    D=DiGraph(loops=True,multiedges=True)
    for c in f:
        c = c[1:-2]
        s1, g, s2 = c.split(', ')
        D.add_edge([ s1, s2, g ])
    f.close()
    return D
edit flag offensive delete link more
0

answered 2013-02-09 22:23:13 +0100

tsang gravatar image

Hi Fidelbc, thanks again for your reply.

I think I figured out how to get the graph done, thanks for all your help.

Just one more small question, my output graph (same as what you got as output), seem like the graphs are not displayed fully, some of the edges or loops at the end of the graph seem cut off. I tried to re-scale the image to make it bigger, but still resulted the same graph. Do you know why this happened? Is there anyway to fix it to make the graph displayed fully?

Thanks a lot.

edit flag offensive delete link more
0

answered 2013-02-07 20:22:11 +0100

tsang gravatar image

Hi Fedelbc, thanks for reminding me update my question! :)

Here is the error I got:

sage: def my_digraph(filename):
          f = open(filename, 'r')
          D=DiGraph(loops=True,multiedges=True)
          for c in f:
              c = c[1:-2]
              s1, g, s2 = c.split(', ')
              D.add_edge([ s1, s2, g ])
          f.close()
          return D
....:     
sage: graph = my_digraph("result")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/mount/autofs/home_stude/tsang/<ipython console> in <module>()

/mount/autofs/home_stude/tsang/<ipython console> in my_digraph(filename)

ValueError: need more than 1 value to unpack

Do you have any suggestions please? Thanks again for your kind help. :)

edit flag offensive delete link more

Comments

Could you add the contents of the file `result`? I think the code above should work if the format is as the one you provided.

fidbc gravatar imagefidbc ( 2013-02-07 23:15:09 +0100 )edit
0

answered 2013-02-06 19:35:50 +0100

tsang gravatar image

Hi Fidelbc, thanks heaps for your help.

You are right that I didn't have 'word: ' at the beginning when I define i and j, but it constantly producing error message says "x is not in the list".

So what I did was print out list S, then I saw it is the format as: ['word: 0000', 'word: 0001', 'word: 0010', 'word: 0011', 'word: 0100', 'word: 0101', 'word: 0110', 'word: 0111', 'word: 1000', 'word: 1001', 'word: 1010', 'word: 1011', 'word: 1100', 'word: 1101', 'word: 1110', 'word: 1111']

That's why I added 'word: ' into the expression for i and j.

I just tried to change to M[i,j] += 1, but still having same error message says "use copy(M) to change a copy of M".

The labels a, b, and c are the labels for edges, as they represent different states for certain group structures.

I also tried your suggested version, but it produce another error message says: "need more than 1 value to unpack".

Do you mind spending a bit more time to help me to look into it please? Thanks a lot for your time.

edit flag offensive delete link more

Comments

Have you tried the code in the answer I posted?

fidbc gravatar imagefidbc ( 2013-02-07 10:46:12 +0100 )edit

Hi Fidelbc, thanks a lot, I did try your suggested answer, but seems like still no plotting outcome, it really gives error says "need more than 1 value to unpack", I don't know why that. Also, I changed my code into "f.readlines()", rather than "f.readline()", it seems start working, however, it still wouldn't plot anything after I typed in "graph.show()". I wonder if it has anything to do just because I am working on mac terminal?

tsang gravatar imagetsang ( 2013-02-07 18:26:09 +0100 )edit

I've tried the code in my answer with your sample input. [This](http://x0.no/ajpe) is a plot of the digraph I get. Please update your question with your current code, current input and the current error message. This thread has gotted a bit thangled up :)

fidbc gravatar imagefidbc ( 2013-02-07 18:59:54 +0100 )edit
0

answered 2013-02-08 00:12:33 +0100

tsang gravatar image

Yes, I know, that's why I don't understand the problem here, I copy and pasted the exact same format as my "result" file, as below:

(0000, a, 1000)
(0000, b, 0000)
(0000, c, 0000)
(0001, a, 1001)
(0001, b, 0001)
(0001, c, 0001)
(0010, a, 1010)
(0010, b, 0010)
(0010, c, 0010)
(0011, a, 1011)
(0011, b, 0011)
(0011, c, 0011)
(0100, a, 1110)
(0100, b, 0100)
(0100, c, 0100)
(0101, a, 1111)
(0101, b, 0101)
(0101, c, 0101)
(0110, a, 1100)
(0110, b, 0111)
(0110, c, 0111)
(0111, a, 1101)
(0111, b, 0110)
(0111, c, 0110)
(1000, a, 0000)
(1000, b, 1000)
(1000, c, 1100)
(1001, a, 0001)
(1001, b, 1001)
(1001, c, 1101)
(1010, a, 0010)
(1010, b, 1010)
(1010, c, 1111)
(1011, a, 0011)
(1011, b, 1011)
(1011, c, 1110)
(1100, a, 0110)
(1100, b, 1110)
(1100, c, 1000)
(1101, a, 0111)
(1101, b, 1111)
(1101, c, 1001)
(1110, a, 0100)
(1110, b, 1100)
(1110, c, 1011)
(1111, a, 0101)
(1111, b, 1101)
(1111, c, 1010)

That's why I really don't understand, it is so strange.

edit flag offensive delete link more

Comments

You code seems to work for me. What I can say from what you have posted is that the file you are providing as input does not correspond to the sample you posted.

fidbc gravatar imagefidbc ( 2013-02-09 00:10:19 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2013-02-06 00:47:34 +0100

Seen: 1,420 times

Last updated: Feb 09 '13