2016-02-24 13 views
28

Biorąc pod uwagę ten początkowy wykresu:Przekazywanie ciągu znaków w celu odświeżenia w agraph.py. Problem z NetworkX i pygraphviz

import networkx as nx 
G=nx.MultiGraph() 
fromnodes=[0,0,1,1,1,1,1,2,3,4,5,5,5,7,8,9,10] 
tonodes=[1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 
dupedgeind=0 
for x,y in zip(fromnodes,tonodes): 
    if G.has_edge(x,y): 
     dupedgeind=dupedgeind+1 
     G.add_edge(x,y,key=dupedgeind) 
    else: 
     dupedgeind=0 
     G.add_edge(x,y,key=dupedgeind) 

ktoś może odtworzyć ten błąd?

pos=nx.nx_agraph.pygraphviz_layout(G,prog='sfdp') 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\networkx\drawing\nx_agraph.py", line 262, in pygraphviz_layout 
    A=to_agraph(G) 
    File "C:\Python27\lib\site-packages\networkx\drawing\nx_agraph.py", line 155, in to_agraph 
    A.add_edge(u,v,key=str(key),**str_edgedata) 
    File "C:\Python27\lib\site-packages\pygraphviz\agraph.py", line 484, in add_edge 
    eh = gv.agedge(self.handle, uh, vh, key, _Action.find) 
KeyError: 'agedge: no key' 

Problem ma coś wspólnego z wywołaniem funkcji agedge Graphviz, wydaje się nie podoba format parametru key; przy zmianie (linia 480 z agraph.py):

... 
    eh = gv.agedge(self.handle, uh, vh, key , _Action.create) 
... 

do

... 
    eh = gv.agedge(self.handle, uh, vh, "a_string" , _Action.create) 
... 

to już nie (ale traci kluczowych metek).

Czy istnieje oczywisty sposób naprawienia tego (aby zachować wartości parametrów key) ? - Nic, co próbuję, wydaje się działać.

Jakie są najbardziej sensowne kolejne kroki debugowania?


Od here, wydaje się, że funkcja c agedge (których nie mogę zobaczyć, jak to jest w .pyd binarnym) ma następujący format:

*agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag) 

gdzie jest char *name klawisz.

Nie mogę się domyślić, dlaczego nie zaakceptuje on dnspe typu str, jak w początkowym błędzie.


Uwaga wersje:

NetworkX - 1,11 pygraphviz - 1.3.1 (zainstalowany z http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygraphviz) Pythona 2,7 (32-bitowe - isntalled przez pyton (x, y)) Windows 7 (64 -bitowa) GraphViz - 2,38

widziałem też ten problem upraw w tych pytaniach:


aktualizacji 1

Próbowałem regulacji wejście key do funkcji agedge do szeregu wariantów tablic Char (np (ct.c_char_p * len(key))(key) (ct to moduł ctypes) na podstawie this).Zmienia to błąd do:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\networkx\drawing\nx_agraph.py", line 262, in pygraphviz_layout 
    A=to_agraph(G) 
    File "C:\Python27\lib\site-packages\networkx\drawing\nx_agraph.py", line 155, in to_agraph 
    A.add_edge(u,v,str(key),**str_edgedata) 
    File "C:\Python27\lib\site-packages\pygraphviz\agraph.py", line 482, in add_edge 
    eh = gv.agedge(self.handle, uh, vh, (ct.c_char_p * len(key))(key), _Action.create) 
TypeError: in method 'agedge', argument 4 of type 'char *' 

UPDATE 2

mogę zmusić go do pracy (ale nie zwracają multigraf) jeśli mogę to zrobić:

W agraph.py zastępując linię

eh = gv.agedge(self.handle, uh, vh, key , _Action.create) 

z

try: 
     # new 
     if key==0: 
      eh = gv.agedge(self.handle, uh, vh, str(0), _Action.create) 
     else: 
      eh = gv.agedge(self.handle, uh, vh, str(1), _Action.create) 

Nie wiem, dlaczego po prostu rzucanie na ciąg str(key) nie działa.

UPDATE 3 - Edycja z funkcją

Znaleziony funkcja tutaj - https://github.com/ellson/graphviz/blob/master/lib/cgraph/edge.c

Agedge_t *agedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, char *name, 
int cflag) 
{ 
    Agedge_t *e; 
    IDTYPE id; 
    int have_id; 
    have_id = agmapnametoid(g, AGEDGE, name, &id, FALSE); 
    if (have_id || ((name == NILstr) && (NOT(cflag) || agisstrict(g)))) { 
     /* probe for pre-existing edge */ 
     Agtag_t key; 
     key = Tag; 
     if (have_id) { 
      key.id = id; 
      key.objtype = AGEDGE; 
     } else { 
      key.id = key.objtype = 0; 
     } 
     /* might already exist locally */ 
     e = agfindedge_by_key(g, t, h, key); 
     if ((e == NILedge) && agisundirected(g)) 
      e = agfindedge_by_key(g, h, t, key); 
     if (e) 
      return e; 
     if (cflag) { 
      e = agfindedge_by_key(agroot(g), t, h, key); 
      if ((e == NILedge) && agisundirected(g)) 
       e = agfindedge_by_key(agroot(g), h, t, key); 
      if (e) { 
       subedge(g,e); 
       return e; 
      } 
     } 
} 

UPDATE 4:

Źródłem błędu jest w this pliku pygraphviz, graphviz_wrap.c, linia 3921:

SWIGINTERN PyObject *_wrap_agedge(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { 
    PyObject *resultobj = 0; 
    Agraph_t *arg1 = (Agraph_t *) 0 ; 
    Agnode_t *arg2 = (Agnode_t *) 0 ; 
    Agnode_t *arg3 = (Agnode_t *) 0 ; 
    char *arg4 = (char *) 0 ; 
    int arg5 ; 
    void *argp1 = 0 ; 
    int res1 = 0 ; 
    void *argp2 = 0 ; 
    int res2 = 0 ; 
    void *argp3 = 0 ; 
    int res3 = 0 ; 
    int res4 ; 
    char *buf4 = 0 ; 
    int alloc4 = 0 ; 
    int val5 ; 
    int ecode5 = 0 ; 
    PyObject * obj0 = 0 ; 
    PyObject * obj1 = 0 ; 
    PyObject * obj2 = 0 ; 
    PyObject * obj3 = 0 ; 
    PyObject * obj4 = 0 ; 
    Agedge_t *result = 0 ; 

    if (!PyArg_ParseTuple(args, char*)"OOOOO:agedge",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; 
    res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Agraph_t, 0 | 0); 
    if (!SWIG_IsOK(res1)) { 
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '""agedge" "', argument " "1"" of type '" "Agraph_t *""'"); 
    } 
    arg1 = (Agraph_t *)(argp1); 
    res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_Agnode_t, 0 | 0); 
    if (!SWIG_IsOK(res2)) { 
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "agedge" "', argument " "2"" of type '" "Agnode_t *""'"); 
    } 
    arg2 = (Agnode_t *)(argp2); 
    res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_Agnode_t, 0 | 0); 
    if (!SWIG_IsOK(res3)) { 
     SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "agedge" "', argument " "3"" of type '" "Agnode_t *""'"); 
    } 
    arg3 = (Agnode_t *)(argp3); 
    res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); 
    if (!SWIG_IsOK(res4)) { 
     SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "agedge" "', argument " "4"" of type '" "char *""'"); 
    } 
    arg4 = (char *)(buf4); 
    ecode5 = SWIG_AsVal_int(obj4, &val5); 
    if (!SWIG_IsOK(ecode5)) { 
     SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "agedge" "', argument " "5"" of type '" "int""'"); 
    } 
    arg5 = (int)(val5); 
    { 
     result = (Agedge_t *)agedge(arg1,arg2,arg3,arg4,arg5); 
     if (!result) { 
      PyErr_SetString(PyExc_KeyError,"agedge: no key"); 
      return NULL; 
     } 
    } 
    resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Agedge_t, 0 | 0); 
    if (alloc4 == SWIG_NEWOBJ) free((char*)buf4); 
    return resultobj; 
    fail: 
     if (alloc4 == SWIG_NEWOBJ) free((char*)buf4); 
     return NULL; 
} 

Albo, to w ciągu this one, graphviz.i, wiersz 68.

Tak czy inaczej, wydaje się, że błąd smyczkowy „agedge: brak klucz” jest zwracany, jeśli agedge zawiedzie z jakiegokolwiek powodu ... Może to coś wspólnego z SWIG.

+0

Po prostu strzał w ciemność, czy próbowałeś rzucić klucz do napisu: 'G.add_edge (x, y, key = str (dupedgeind))'? –

+0

@ MarkkuK. Dzięki. Problem jednak utrzymuje się. – atomh33ls

+0

Jak to jest związane z C? –

Odpowiedz

1

Spróbuj zmienić nazwę zmiennej z "key" na coś innego, jak "temp_key". Chodzi mi o to, że możliwe jest, że ty (lub jakikolwiek wcześniej importowany moduł) zadeklarował zmienną "kluczową" typu "ciąg" przed ...?

Podobno jeśli trwania:

eh = gv.agedge(self.handle, uh, vh, key , _Action.create) 

ale nie działa:

eh = gv.agedge(self.handle, uh, vh, "key" , _Action.create) 

daje żadnego problemu, to może być tylko w stosunku do "klucz" typu zmiennej .. ty spróbuj tego:

eh = gv.agedge(self.handle, uh, vh, str(key) , _Action.create) 

lub eh = gv.agedge(self.handle, uh, vh, unicode(key) , _Action.create)

Zintegruj str()/unicode() w oryginalnym kodzie podać:

import networkx as nx 
G=nx.MultiGraph() 
fromnodes=[0,0,1,1,1,1,1,2,3,4,5,5,5,7,8,9,10] 
tonodes=[1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 
dupedgeind=0 
for x,y in zip(fromnodes,tonodes): 
    if G.has_edge(x,y): 
     dupedgeind=dupedgeind+1 
     G.add_edge(x,y,key=str(dupedgeind)) 
     #G.add_edge(x,y,key=unicode(dupedgeind)) 
    else: 
     dupedgeind=0 
     G.add_edge(x,y,key=str(dupedgeind)) 
     #G.add_edge(x,y,key=unicode(dupedgeind)) 

zarówno (str & wersja Unicode) działa poprawnie w systemie Linux.

poważaniem

+0

Dzięki. Próbowałem - nadal miał ten sam błąd. – atomh33ls

+0

Najlepiej wyczyścić ponownie networkx. –

+0

Dokładny ten sam błąd tutaj: http://stackoverflow.com/questions/35007046/how-to-draw-parallel-edges-in-networkx-graphviz wygląda na zdecydowanie związany z problemem instalacji/kompilacji pakietu Microsoft Windows. –

0

Moje środowisko jest python2.7 32-bitowy Windows 7 64-bit i robię projekt, który wykorzystuje pygraphviz/graphviz narysować FSM.Podczas użytkowania doszedłem również po drugiej stronie tego samego błędu

KeyError: 'agedge: no key'

Ten projekt ma zamkniętą problem, który stwierdza, że ​​błąd pokazuje tylko, gdy trzeba przejść gdzie państwo źródła jest taki sam jak stan docelowy. Lub w prostszy sposób, gdy stan wskazuje na siebie.

Mogę potwierdzić, że dostaję błąd, gdy są stany wskazujące na siebie, natomiast jeśli utworzę wykres, który nie ma żadnych takich przejść, to działa i prawidłowo tworzy plik obrazu (.png) w moim przypadku.

https://github.com/tyarkoni/transitions/issues/133

PS: Nie sądzę, że uzasadnia to pełną odpowiedź, ponieważ nie jest to kompletne rozwiązanie. Ale niestety nie mam wystarczającej liczby punktów reputacji, aby to skomentować.

+0

Poczekaj, aż uzyskasz reputację. Jesteś blisko. Oprócz tego. Nie publikuj linku jako odpowiedzi Podaj jak najwięcej w treści odpowiedzi i odnośniku do strony. – Masoud

+0

Edytowałem swoją odpowiedź. Czy to jest lepsze? – Satrapes

+0

Pewnie, że tak. Dziękuję Ci. – Masoud

Powiązane problemy