如何在Windows上使用pygraphviz运行neato

11

我正在尝试在Python(v 2.7)中使用pygraphviz和networkx创建网络图。我在stackoverflow上找到了一个看起来非常有用的脚本:

import networkx as nx
import numpy as np
import string
import pygraphviz

dt = [('len', float)]
A = np.array([(0, 0.3, 0.4, 0.7),
               (0.3, 0, 0.9, 0.2),
               (0.4, 0.9, 0, 0.1),
               (0.7, 0.2, 0.1, 0)
               ])*10
A = A.view(dt)

G = nx.from_numpy_matrix(A)
G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))    

G = nx.to_agraph(G)

G.node_attr.update(color="red", style="filled")
G.edge_attr.update(color="blue", width="2.0")

G.draw('/tmp/out.png', format='png', prog='neato')

我在最后一行遇到了错误,基本上它找不到neato:

"ValueError:在路径中找不到程序neato。"

这个错误是关于pygraphviz的agraph.py文件的问题,但当我查看agraph.py时,我看不出有什么可能会导致问题。

有什么想法可以解决这个问题吗? 我正在使用Windows和IDLE进行编码。 谢谢!


我也在WSL 2中遇到了那个错误。 - Soren
5个回答

13

我曾遇到同样的问题。以下是我在Windows上安装pygraphvis时所采取的步骤,以防其他人也在苦苦挣扎。

首先,我安装了graphviz。尝试通过pip安装pygraphvis,但它拒绝工作。最终,我找到了非官方的Windows二进制文件,因此我安装了它。现在导入模块可以工作了,但调用G.layout()会出现上述错误。

调用neato -V可行,说明它已经在我的PATH中了。我发现问题在于Python是在安装pygraphvis之前创建的命令提示符中运行的,因此PATH没有更新。重启命令提示符可以解决这个问题,但会出现一个新的错误,关于C:\ Program不是有效的命令。

我想pygraphvis可能未正确引用路径,这意味着它在Program Files中的空格处被截断了。我通过将其链接到没有空格的路径来解决了这个问题。

mklink /d C:\ProgramFilesx86 "C:\Program Files (x86)"

请注意,此操作必须以管理员模式运行。您可以通过转到开始菜单,输入cmd,然后按Ctrl+Shift+Enter来实现。

之后,我编辑了我的PATH以引用符号链接,重新启动了cmd,一切正常。


为了清晰起见,在Windows10中现在很难访问“路径”。 要访问它,请右键单击开始按钮(左下角),然后单击“搜索”,然后输入“控制面板”,然后单击窗口右侧的“系统”,然后在窗口左侧单击“高级系统参数”。 更改路径后,请记得关闭并重新打开Python和命令提示符以更新更改的路径。 - sol

4
问题在于pygraphviz调用一个外部程序,图形套件的一部分叫做neato来绘制图形。问题是你没有安装graphviz,当Python试图调用它时会抱怨找不到它。实际上,pygraphviz只是一个包装器,让你有可能从python内部调用graphviz,但本身并不做任何事情,并且默认情况下不安装graphviz。
最简单的解决方案是尝试使用不同的绘图解决方案而不是neato。可接受的选项为:
neato
dot
twopi
circo
fdp
nop

尝试其中一个并查看它们是否有效。否则,您可以安装graphviz,这将为您提供所需的程序。它是一款开源程序,在每个平台上都可用,因此安装它不应该成为问题。
请参见http://www.graphviz.org/
如果您只需要图形的草图,则可以在networkx图上使用networkx.draw函数,该函数使用matplotlib创建交互式绘图。
import networkx as nx
G = G=nx.from_numpy_matrix(A)
nx.draw(G)

首先,感谢您的回复。我已经安装了Graphviz。现在,当我运行我的脚本时,我会得到以下错误: Traceback (most recent call last): File "C:/Python27/2_5.py", line 22, in <module> G.draw('/tmp/out.png', format='png', prog='neato') File "C:\Python27\lib\site-packages\pygraphviz\agraph.py", line 1422, in draw fh=self._get_fh(path,'w+b') File "C:\Python27\lib\site-packages\pygraphviz\agraph.py", line 1458, in _get_fh fh = file(path,mode=mode) IOError: [Errno 2] No such file or directory: '/tmp/out.png' - Amlanza
创建文件 /tmp/out.png 时出现问题。这可能是由于操作系统的原因。在所有 Linux 发行版中,/tmp 是一个普通目录,因此只需要创建该文件即可。如果您正在使用 Windows,则该目录可能不存在,因此会出现错误(您正在尝试在不存在的目录中创建文件)。如果您将其替换为仅使用“out.png”而不指定目录,则应该可以在当前目录中创建它而不会出现问题。让我知道这是否奏效! - EnricoGiampieri
现在,了解如何使用其他选项也是很好的。 - Soren

2
您的问题在于缺少“neato”软件。
“neato”是图形可视化软件graphviz套件的一部分,您可以从这里安装到您的电脑上(我使用了“.msi”文件)。
现在,“neato”已经“安装”了,但您的系统不知道它在哪里。因此,将包含“neato.exe”的目录添加到您的“PATH”环境变量中。在Win10中,可以通过以下步骤完成:点击“开始” -> 编辑帐户的环境变量 -> 选择上窗口中的路径 -> 编辑 -> 新建 -> C:\Program Files (x86)\Graphviz2.38\bin\或者您的安装目录。

1
总的来说,这个答案非常好。基本思路对我来说是正确的,但出于某些原因,将该路径添加到 Env. Vars. 中并没有起作用。我也会发布我的解决方案。 - bart cubrich

2

这个错误可能有多个原因,但如果是由于缺少到graphviz模块的路径 [neato,dot,twopi,circo,fdp,nop] 导致的,则有一个我使用过的hack方法。目前我正在询问正确的解决方案,但您可以使用此方法。

if  not 'C:\\Program Files (x86)\\Graphviz2.38\\bin' in os.environ["PATH"]: 
    os.environ["PATH"] += os.pathsep + 'C:\\Program Files (x86)\\Graphviz2.38\\bin' 

在你的脚本开头加入以下代码。总的来说,如果你的Graphviz文件保存在其他地方:
graph_path='your_bin_folder_path'
    if  not graph_path in os.environ["PATH"]: 
        os.environ["PATH"] += os.pathsep + graph_path

特别是在Windows 10上,使用Anaconda Navigator和Python版本3.7,这个方法可以奏效。


既然你说我的答案对你没用,那么请问你是否按照我描述的方式设置了路径变量后关闭并重新打开了终端?因为这是必须要做的事情,但如果你已经这样做了,我也不知道问题出在哪里。 - lucidbrot
哦,那可能就是我所需要的。 - bart cubrich
1
@bartcubrich,我再感谢不过了。你的解决方案为我解决了问题。正确的解决方案就是能够起作用的。 - Bowen Liu

1

尝试使用以下方法来查看pygraphviz认为你的外部程序所在的位置:

# Get paths of graphviz programs
import pygraphviz as pgv

A = pgv.AGraph()
progs_list = ['neato', 'dot', 'twopi', 'circo', 'fdp', 'nop', 'wc', 'acyclic', 'gvpr',
              'gvcolor', 'ccomps', 'sccmap', 'tred', 'sfdp', 'unflatten']
for prog in progs_list:
    try:
        runprog = A._get_prog(prog)
        print(f'{runprog}')
    except ValueError as e:
        print(f'{prog} gets this error: {str(e).strip()}')

在查看结果后,需要在IDE外安装Graphviz并在系统控制面板中设置Path环境变量等,这是一项繁琐的工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接