Python 3.4在生成一些 - 但不是全部 - 具有分段错误11的Cartopy地图时崩溃

use*_*097 5 python gis matplotlib fink cartopy

我在使用Python 3.4运行El Capitan 10.11.6的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
Run Code Online (Sandbox Code Playgroud)

然后我使用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
Run Code Online (Sandbox Code Playgroud)

以上似乎符合以下所列的所有Cartopy依赖要求:http://scitools.org.uk/cartopy/docs/v0.15/installing.html

然后我安装了Cartopy,确保与fink一起安装的地理库(如果这是正确的术语):

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
Run Code Online (Sandbox Code Playgroud)

我可以在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()
Run Code Online (Sandbox Code Playgroud)

就像这段代码一样:

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()
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)

当代码在终端中逐行输入时,所有行都是正常的,直到输入最后两行中的任何一行.

命令行中生成的唯一错误消息是:

Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)

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

use*_*097 4

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

\n

我在 Cartopy GitHub 页面上发布了一个问题 ( https://github.com/SciTools/cartopy/issues/879 ) 上发布了一个问题,其中 QuLogic 建议使用以下方法重新安装 shapely 来阻止分段错误:

\n
    pip uninstall shapely; pip install --no-binary :all: shapely\n
Run Code Online (Sandbox Code Playgroud)\n

这确实阻止了分段错误 11,但运行“问题”代码会产生一个错误,表明无法找到 geos_c,即使它存在。确切的错误是:

\n
\n

OSError:无法找到 lib geos_c 或加载其任何变体 [\'/Library/Frameworks/GEOS.framework/Versions/Current/GEOS\'、\'/opt/local/lib/libgeos_c.dylib\']。

\n
\n

似乎代码坚持在预定义位置查找该库,并拒绝查看 fink 安装该库的位置,即使我已将位置添加到 .bash_profile 文件中。解决方案是在该预定义位置创建一个指向 fink 安装库的符号链接。希望这是有道理的。(请参阅 Jace Browning,在安装 Shapely 时无法找到 OSError geos_c)。

\n

这是我的整个解决方案的摘要,以防对其他人有所帮助。任何改进建议都将受到欢迎。

\n
    \n
  1. 郑重声明,我的设置是在 iMac 上运行的 Mac OS 10.11.6 (El Capitan) 上的标准(非管理员)帐户。不过,如有必要,我也可以访问管理员帐户。

    \n
  2. \n
  3. 使用 python.org 提供的安装程序安装了 Python 3.6 版本

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

    \n
  6. \n
  7. Python 3.6 安装在 /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 中。-m venv使用以下命令创建虚拟环境(称为 venv36) :

    \n
  8. \n
\n

在命令行:

\n
    $ mkdir <name_of_directory_for_virtual_env>\n    $ cd <name_of_directory_for_virtual_env>\n    $ /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 -m venv venv36\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 在用户帐户中,使用 nano 编辑 .bash_profile 文件以包含 fink 安装 libgeos3.6.1 的位置的路径:
  2. \n
\n

在命令行:

\n
    $ cd\n    $ nano .bash_profile\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
    GEOS_CONFIG="/sw/opt/libgeos3.6.1/bin/geos-config"; export GEOS_CONFIG\n    GEOS_DIR="/sw/opt/libgeos3.6.1"; export GEOS_DIR\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 激活虚拟环境并pip安装所需的软件包。pandas 和 jupyter 软件包是可选的,但为什么您不想安装它们呢?
  2. \n
\n

在命令行中:

\n
    $ cd <path_to_virtual_environment>\n    $ source venv36/bin/activate\n    \n    (venv36) $ pip install cython\n    (venv36) $ pip install numpy\n    (venv36) $ pip install --no-binary :all: shapely\n    (venv36) $ pip install pyshp\n    (venv36) $ pip install pyproj\n    (venv36) $ pip install six\n    (venv36) $ pip install matplotlib\n    \n    (venv36) $ export CPLUS_INCLUDE_PATH=/sw/include/gdal2/\n    (venv36) $ export C_INCLUDE_PATH=/sw/include/gdal2/\n    (venv36) $ pip install gdal\n    (venv36) $ pip install pillow\n    (venv36) $ pip install pyepsg\n    (venv36) $ pip install scipy\n    (venv36) $ pip install OWSLib\n    (venv36) $ pip install mock nose pep8\n    (venv36) $ pip install pandas\n    (venv36) $ pip install jupyter\n    \n    (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\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 最后,在 /opt/local/lib/ 中添加了一个符号链接(这是 cartopy \xe2\x80\x93 或其他一些包 \xe2\x80\x93 坚持寻找 libgeos 的地方),该链接指向由 fink 安装的 libgeos 库(称为 libgeos_c.1.dylib)。如果 /opt/local/lib 路径(或其中的一部分)尚不存在,则可能需要创建它。
  2. \n
\n

然后,在命令行中:

\n
    $ cd /opt/local/lib\n    $ sudo ln -s /sw/opt/libgeos3.6.1/lib/libgeos_c.1.dylib libgeos_c.dylib\n
Run Code Online (Sandbox Code Playgroud)\n

就是这样。在激活的虚拟环境中,打开jupyter-notebook。如果您希望在笔记本中绘制地图,请确保第一行包含以下内容:

\n
%matplotlib inline\n
Run Code Online (Sandbox Code Playgroud)\n

然后将以下内容添加到下一个单元格:

\n
import cartopy\nimport matplotlib.pyplot as plt\n\nax = plt.axes(projection=cartopy.crs.PlateCarree())\n\nax.add_feature(cartopy.feature.LAND)\nax.add_feature(cartopy.feature.OCEAN)\nax.add_feature(cartopy.feature.COASTLINE)\nax.add_feature(cartopy.feature.BORDERS, linestyle=\':\')\nax.add_feature(cartopy.feature.LAKES, alpha=0.5)\nax.add_feature(cartopy.feature.RIVERS)\n\nax.set_extent([-20, 60, -40, 40])\n\nplt.show()\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

cartopy代码生成的地图

\n

就是这样了。希望能帮助到你。任何改进意见或建议将不胜感激。

\n