Python 3.4在生成某些Cartopy地图时崩溃,但并非所有地图都是如此,并显示分段错误11。

5
我在运行 El Capitan 10.11.6 并使用 Python 3.4 的 Mac 上安装了 Python 映射工具 Cartopy。我可以使用 Cartopy 成功绘制一些地图,但在某些情况下,Python 内核会因 Segmentation Fault 11 而失败。
我希望有一个易于从计算机中删除的设置,以防需要时。因此,我使用 fink 安装了 Python 3.4 和必要的依赖项:
$ fink install python34
$ fink install gdal2
$ fink install gdal2-dev
$ fink install proj
$ fink install libproj9

我随后使用pyvenv(也尝试了virtualenv和venv)创建了一个虚拟环境并激活它。
在激活的虚拟环境中,我使用pip安装了以下内容:
$ pip install cython        # Successfully installed cython-0.25.2
$ pip install numpy         # Successfully installed numpy-1.12.1
$ pip install shapely       # Successfully installed shapely-1.5.17.post1
$ pip install pyshp         # Successfully installed pyshp-1.2.10
$ pip install pandas        # Successfully installed pandas-0.19.2 python-dateutil-2.6.0 pytz-2017.2 six-1.10.0
$ pip install matplotlib    # Successfully installed cycler-0.10.0 matplotlib-2.0.0 pyparsing-2.2.0
$ pip install pillow        # Successfully installed olefile-0.44 pillow-4.1.0
$ pip install pyepsg        # Successfully installed pyepsg-0.3.1
$ pip install scipy         # Successfully installed scipy-0.19.0
$ pip install OWSLib        # Successfully installed OWSLib-0.14.0 pyproj-1.9.5.1 requests-2.13.0
$ pip install mock          # Successfully installed mock-2.0.0 pbr-3.0.0
$ pip install nose          # Successfully installed nose-1.3.7
$ pip install pep8          # Successfully installed pep8-1.7.0
$ pip install jupyter       # Successfully installed MarkupSafe-1.0 appnope-0.1.0 backports-abc-0.5 bleach-2.0.0 decorator-4.0.11 entrypoints-0.2.2 html5lib-0.999999999 ipykernel-4.6.1 ipython-6.0.0 ipython-genutils-0.2.0 ipywidgets-6.0.0 jedi-0.10.2 jinja2-2.9.6 jsonschema-2.6.0 jupyter-1.0.0 jupyter-client-5.0.1 jupyter-console-5.1.0 jupyter-core-4.3.0 mistune-0.7.4 nbconvert-5.1.1 nbformat-4.3.0 notebook-5.0.0 pandocfilters-1.4.1 pexpect-4.2.1 pickleshare-0.7.4 prompt-toolkit-1.0.14 ptyprocess-0.5.1 pygments-2.2.0 pyzmq-16.0.2 qtconsole-4.3.0 simplegeneric-0.8.1 terminado-0.6 testpath-0.3 tornado-4.5.1 traitlets-4.3.2 typing-3.6.1 wcwidth-0.1.7 webencodings-0.5.1 widgetsnbextension-2.0.0

以上内容似乎满足了在以下网址列出的所有Cartopy依赖需求:http://scitools.org.uk/cartopy/docs/v0.15/installing.html

然后我安装了Cartopy,并确保使用与fink安装的geos库构建(如果这是正确的术语):

pip install --global-option=build_ext --global-option="-I/sw/opt/libgeos3.5.0/include" --global-option="-L/sw/opt/libgeos3.5.0/lib"  cartopy
                             # Successfully installed cartopy-0.14.2

我可以在Jupyter笔记本或终端中运行Python,并且可以无错误地导入Cartopy。我从Cartopy网站下载了一些示例代码来测试安装。

以下示例完美地工作:

import matplotlib
matplotlib.use("TkAgg")
cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Mollweide())
ax.stock_img()
plt.show()

就像这段代码一样:

import os
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt

from cartopy import config
import cartopy.crs as ccrs

fig = plt.figure(figsize=(8, 12))

# get the path of the file. It can be found in the repo data directory.
fname = os.path.join(config["repo_data_dir"],
                     'raster', 'sample', 'Miriam.A2012270.2050.2km.jpg'
                     )
img_extent = (-120.67660000000001, -106.32104523100001, 13.2301484511245, 30.766899999999502)
img = plt.imread(fname)

ax = plt.axes(projection=ccrs.PlateCarree())
plt.title('Hurricane Miriam from the Aqua/MODIS satellite\n'
          '2012 09/26/2012 20:50 UTC')

# set a margin around the data
ax.set_xmargin(0.05)
ax.set_ymargin(0.10)

# add the image. Because this image was a tif, the "origin" of the image is in the
# upper left corner
ax.imshow(img, origin='upper', extent=img_extent, transform=ccrs.PlateCarree())
ax.coastlines(resolution='50m', color='black', linewidth=1)

# mark a known place to help us geo-locate ourselves
ax.plot(-117.1625, 32.715, 'bo', markersize=7, transform=ccrs.Geodetic())
ax.text(-117, 33, 'San Diego', transform=ccrs.Geodetic())

plt.show()

但是这段代码导致内核崩溃:

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import cartopy

ax = plt.axes(projection=cartopy.crs.PlateCarree())

ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.add_feature(cartopy.feature.LAKES, alpha=0.5)
ax.add_feature(cartopy.feature.RIVERS)

ax.set_extent([-20, 60, -40, 40])

plt.show()

当在终端逐行输入代码时,所有行都没问题,直到输入最后两行之一为止。 唯一在命令行产生的错误消息是:
Segmentation fault: 11

有人遇到过这个问题的原因和解决方法吗?

你能否将你看到的错误信息复制/粘贴到你的帖子末尾?这可能有助于其他人识别问题。 - ajdawson
唯一的信息是“分段错误:11”。已添加到问题中。 - user1718097
2个回答

4

最终成功取得了一些进展,我将总结我的解决方案。它可能不能解决所有问题,但它确实解决了我最初遇到的问题。

我在Cartopy GitHub页面上发布了一个问题(https://github.com/SciTools/cartopy/issues/879),QuLogic建议重新安装shapely来防止分段错误。

    pip uninstall shapely; pip install --no-binary :all: shapely

这确实解决了段错误11的问题,但运行“问题”代码后出现了一个错误,提示找不到geos_c,即使它存在。确切的错误是:

OSError: Could not find lib geos_c or load any of its variants ['/Library/Frameworks/GEOS.framework/Versions/Current/GEOS', '/opt/local/lib/libgeos_c.dylib']。

看起来代码坚持在预定义位置查找此库,拒绝查看fink安装库的位置,即使我已将该位置添加到我的.bash_profile文件中。解决方案是在该预定义位置创建一个符号链接,指向fink安装的库。希望这有意义。(请参见Jace Browning的OSError geos_c could not be found when Installing Shapely)。

因此,以下是我整个解决方案的摘要,以帮助其他人。欢迎提出改进建议。

  1. 记录一下,我使用的是iMac上运行的Mac OS 10.11.6(El Capitan)上的标准(非管理员)账户。但如果需要,我也可以访问管理员账户。

  2. 使用python.org提供的安装程序安装Python 3.6版本。

  3. 作为管理员,使用fink安装了gdal2、gdal2-dev、libproj9、libgeos3.6.1。(还使用fink安装了python3.6的一个版本、gdal-py36、freetype、freetype219、cairo、gsl、sqlite3和libspatialite7,但不确定这些软件包是否绝对必要。)

  4. Python 3.6安装在/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6中。使用-m venv创建了一个虚拟环境(名为venv36),如下所示:

在命令行中:

    $ mkdir <name_of_directory_for_virtual_env>
    $ cd <name_of_directory_for_virtual_env>
    $ /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 -m venv venv36

在用户账户中,使用nano编辑.bash_profile文件,将路径添加到fink安装的libgeos3.6.1所在的位置:

在命令行中:

    $ cd
    $ nano .bash_profile

将以下行添加到.bash_profile文件中并保存(ctrl-O):

    GEOS_CONFIG="/sw/opt/libgeos3.6.1/bin/geos-config"; export GEOS_CONFIG
    GEOS_DIR="/sw/opt/libgeos3.6.1"; export GEOS_DIR
  1. 激活虚拟环境并安装所需的包。pandas 和 jupyter 包是可选的,但为什么不安装呢?

在命令行中输入:

    $ cd <path_to_virtual_environment>
    $ source venv36/bin/activate
    
    (venv36) $ pip install cython
    (venv36) $ pip install numpy
    (venv36) $ pip install --no-binary :all: shapely
    (venv36) $ pip install pyshp
    (venv36) $ pip install pyproj
    (venv36) $ pip install six
    (venv36) $ pip install matplotlib
    
    (venv36) $ export CPLUS_INCLUDE_PATH=/sw/include/gdal2/
    (venv36) $ export C_INCLUDE_PATH=/sw/include/gdal2/
    (venv36) $ pip install gdal
    (venv36) $ pip install pillow
    (venv36) $ pip install pyepsg
    (venv36) $ pip install scipy
    (venv36) $ pip install OWSLib
    (venv36) $ pip install mock nose pep8
    (venv36) $ pip install pandas
    (venv36) $ pip install jupyter
    
    (venv36) $ pip install --global-option=build_ext --global-option="-I/sw/opt/libgeos3.6.1/include" --global-option="-L/sw/opt/libgeos3.6.1/lib"  cartopy
  1. 最后,在/opt/local/lib/中添加了一个符号链接(cartopy或其他软件包坚持要查找的libgeos所在的位置),该链接指向由fink安装的libgeos库(名为libgeos_c.1.dylib)。如果/opt/local/lib路径(或其中的某些部分)不存在,则可能需要创建它。

然后,在命令行中输入:

    $ cd /opt/local/lib
    $ sudo ln -s /sw/opt/libgeos3.6.1/lib/libgeos_c.1.dylib libgeos_c.dylib

在已激活的虚拟环境下打开jupyter-notebook。如果您想在notebook中绘制地图,请确保第一行包含以下内容:
%matplotlib inline

然后在下一个单元格中添加以下内容:
import cartopy
import matplotlib.pyplot as plt

ax = plt.axes(projection=cartopy.crs.PlateCarree())

ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.add_feature(cartopy.feature.LAKES, alpha=0.5)
ax.add_feature(cartopy.feature.RIVERS)

ax.set_extent([-20, 60, -40, 40])

plt.show()

当代码运行时,它可能会产生一个警告(Failed CDLL(/Library/Frameworks/GEOS.framework/Versions/Current/GEOS)),但希望它仍然能够生成以下图像:

Map produced by cartopy code

就是这样。希望能对您有所帮助。如有任何意见或建议,我们将不胜感激。


1
我会在这里记录我解决这个问题的经验,希望能帮助到其他人。
如何在MacOS上安装Cartopy:
我使用的是MacOS 10.12.6,在Python 3.7.0的虚拟环境中(因此我没有使用conda)。
  1. Following the requirements, install required Python libraries if you don't have them yet:

    pip install numpy  
    pip install Cython  
    pip install --no-binary :all: shapely  
    pip install pyshp  
    pip install six  
    

    Obtaining the following versions in my case:

    numpy==1.15.3
    Cython==0.29
    Shapely==1.6.4.post2
    pyshp==2.0.1
    six==1.11.0
    
  2. Also, I brew installed:

    brew install proj  
    brew install geos
    

    Getting versions:

    proj --> Rel. 5.2.0, September 15th, 2018
    geos-config --version --> 3.7.0
    

    Also add export GEOS_DIR=/usr/local/Cellar/geos/3.7.0/ to my ~/.bash_profile.

  3. Finally, pip install Cartopy:

    pip install Cartopy
    Cartopy==0.17.0
    

原则上,使用brew安装geos应该足够(我在几个地方读到Kyng Chaos网站也可以)。显然,对我来说的障碍

pip install --no-binary :all: shapely

这是什么的解释?

查看 Shapely安装说明

如果您想从源代码构建 Shapely 以便与其他依赖于 GEOS(例如 cartopy 或 osgeo.ogr)的模块兼容,或者想要使用不同版本的 GEOS,而不是项目轮子中包含的版本,则应首先在系统上安装 GEOS 库、Cython 和 Numpy(使用 apt、yum、brew 或其他方式),然后将 pip 指向忽略二进制轮子。

结论:我认为这应该在 Mac 用户的 Cartopy 安装说明中的某个地方包含。


正如user1718097所提到的那样,在Cartopy的GitHub存储库中存在一个问题,涉及此信息。


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