无法导入matplotlib._png(pylab)

Ame*_*ina 1 matplotlib

我无法import matplotlib._png:

import matplotlib._png as _png ImportError: /home/james/opt/python/virtualenvs/work/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-linux-x86_64.egg/matplotlib/_png.so:undefined symbol:png_set_longjmp_fn

这个错误阻止我运行import pylab(最终导入这个matplotlib._png).

我安装了matplotlib从源代码,并确保与本地安装(添加路径/home/james/local),以basedir在setupext.py运行前python setup.py install.

REQUIRED DEPENDENCIES AND EXTENSIONS
                 numpy: yes [version 1.7.1]
              dateutil: yes [using dateutil version 2.1]
               tornado: yes [using tornado version 3.0.1]
             pyparsing: yes [using pyparsing version 1.5.7]
                 pycxx: yes [Couldn't import.  Using local copy.]
                libagg: yes [pkg-config information for 'libagg' could not
                        be found Using local copy.]
              freetype: yes [version 16.0.10]
                   png: yes [version 1.2.10]
Run Code Online (Sandbox Code Playgroud)

我的研究到目前为止:

从上面可以看出,matplotlib似乎找到版本,1.2.10即使我的版本/home/james/local是1.6.2:

$ find . -iname '*libpng*'                                                                                                  
./libpng16.so.16.1.0
./libpng16.so
./libpng16.so.16
./libpng16.a
./libpng.a
./libpng.so
./libpng16.la
./pkgconfig/libpng.pc
./pkgconfig/libpng16.pc
./libpng.la
Run Code Online (Sandbox Code Playgroud)

更具体地说,我修改了以下行setupext.py:

return basedir_map.get(sys.platform, ['/home/james/local', '/usr/local', '/usr'])
Run Code Online (Sandbox Code Playgroud)

但matplotlib似乎找到了系统版本:

$ locate libpng
/usr/lib/libpng.so
/usr/lib/libpng.so.3
/usr/lib/libpng.so.3.10.0
/usr/lib/libpng12.a
/usr/lib/libpng12.so
/usr/lib/libpng12.so.0
/usr/lib/libpng12.so.0.10.0
Run Code Online (Sandbox Code Playgroud)

这可能是问题吗?为什么我无法导入matplotlib._png?

更新:

看一下setupext.py,看起来像python setup install查询pkg-config通过该SetupPackage方法_check_for_pkg_config来确定我已经安装的libpng的版本.事实证明,这pkg-config是返回系统安装:

$ pkg-config --libs libpng
-lpng12
Run Code Online (Sandbox Code Playgroud)

即使我已经更新basedir了matplotlib setupext.py,LD_LIBRARY_PATH并使它们指向libpng我本地安装的更新版本.

关于如何pkg-config返回正确版本的任何想法?

小智 5

这是一个pkg-config问题; matplotlib的安装(不幸的是,或许不是)过于依赖pkg-config输出.

假设你以正常方式构建libpng,你的pkgconfig子目录应该/home/james/local/lib包含libpng.pc(和libpng16.pc).当setupext.py运行pkg-config,后者当然应该尝试拿起正确的.pc文件的libpng.为此,使用该PKG_CONFIG_PATH变量并将其指向pkgconfig子目录:

$ export PKG_CONFIG_PATH=/home/james/local/lib/pkgconfig
Run Code Online (Sandbox Code Playgroud)

然后,再次安装matplotlib,看到它现在找到了正确的libpng版本:

$ python setup.py build
basedirlist is: ['/usr/local', '/usr']
============================================================================
BUILDING MATPLOTLIB
            matplotlib: 1.1.0
                python: 2.7.4 (default, Apr  8 2013, 16:36:47)  [GCC 4.4.5]
              platform: linux2

REQUIRED DEPENDENCIES
                 numpy: 1.7.0
             freetype2: 12.0.6

OPTIONAL BACKEND DEPENDENCIES
                libpng: 1.6.1
               Tkinter: Tkinter: 81008, Tk: 8.4, Tcl: 8.4
Run Code Online (Sandbox Code Playgroud)

(对我来说,当然使用不同的PKG_CONFIG_PATH.是的,我可能想升级一些依赖项.)

请注意,我甚至没有改变basedirlist; 它只是在默认情况下.如果pkg-config现在无法获取其他包,只需添加更多目录PKG_CONFIG_PATH与冒号之间.但我想这应该足够了.