I have a DataFrame network_df
consisting of an edge list
G = nx.from_pandas_edgelist(network_df,source='Parent Node',target= 'Child Node',create_using=nx.DiGraph())
I'm using pygraphviz_layout
to calculate the position of each node in G
pos = pygraphviz_layout(G,prog="dot", args='-Gnodesep=10-Goverlap=false')
But this raises the following error:
Exception has occurred: KeyError
Traceback (most recent call last):
File "C:\..\Python37\lib\site-packages\pygraphviz\agraph.py", line 1615, in __new__
nh = gv.agnode(graph.handle, n.encode(graph.encoding), _Action.find)
KeyError: 'agnode: no key'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\...\Python37\lib\site-packages\networkx\drawing\nx_agraph.py",
line 293, in pygraphviz_layout
node = pygraphviz.Node(A, n)
File "C:\...\Python37\lib\site-
packages\pygraphviz\agraph.py", line 1617, in __new__
raise KeyError("Node %s not in graph." % n)
KeyError: "Node ('', '', 'A /// Standard', 'Event A') not in graph."
But when I do
key = ('', '', 'A /// Standard', 'Event A')
print(key in G.nodes())
This prints True
meaning that the node is indeed in the Graph, what can I be doing wrong here?
Also, if I use some other function to calculate the position, it works
pos = nx.spring_layout(G)
What is wrong here? pygraphviz_layout
has worked without any problems before for other datasets.
The following should work:
import networkx as nx
# an example graph with string (names) as nodes
g = nx.les_miserables_graph()
labels_to_int = {}
int_to_labels = {}
for i, label in enumerate(g):
labels_to_int[label] = i
int_to_labels[i] = label
# update labels to ints with
nx.relabel_nodes(g, labels_to_int, copy=False)
print(g.nodes)
# Tested only with the following since I have pygraphviz not installed
pos = nx.kamada_kawai_layout(g)
# pos = pygraphviz_layout(G,prog="dot", args='-Gnodesep=10-Goverlap=false')
# changes back to original labels
nx.relabel_nodes(g, int_to_labels, copy=False)
label_pos = {label: pos[labels_to_int[label]] for label in g}
print(label_pos)
# {'Napoleon': array([0.73407672, 0.66096404]), 'Myriel': array([0.67744174, 0.53499379]), ....
print(g.nodes)
# ['Napoleon', 'Myriel', ...
The reason for you error is probably that pygraphviz
cannot work with arbitrary (hashable) nodes unlike networkx
. Therefore, above code simply cast the node labels to int
before calling the layout and revert the changes in the nodes and the pos
dict.
I've found that using arbitrary hashable nodes doesn't work with the pygraphviz
backend, but it does with pydot
:
import networkx as nx
from networkx.drawing.nx_pydot import graphviz_layout
g = ...
pos = graphviz_layout(g, "dot")
nx.draw_networkx(g, pos=pos)
The key point here is importing graphviz_layout
from networkx.drawing.nx_pydot
and not networkx.drawing.nx_agraph
or elsewhere.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.