Сбой Python 3.4 при создании некоторых - но не всех - картографических карт с ошибкой сегментации 11
Я установил инструмент отображения карт Python Cartopy на Mac под управлением El Capitan 10.11.6 с Python 3.4. Я могу использовать Cartopy для успешного построения некоторых карт, но в некоторых случаях ядро Python умирает с ошибкой сегментации 11.
Я хотел настройки, которые я мог бы легко удалить с моего компьютера, если возникнет такая необходимость. Поэтому я установил Python 3.4 и необходимые зависимости с помощью fink:
$ 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, обеспечив сборку (если это правильный термин) библиотеки geos, установленной с помощью 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
Я мог запускать Python либо в блокноте Jupyter, либо в терминале, и это позволило мне импортировать 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
Кто-нибудь сталкивался с причиной и решением этой проблемы?
1 ответ
Наконец-то удалось добиться определенного прогресса, поэтому я подведу итоги своего решения. Возможно, это не решит все проблемы, но оно решило проблему, с которой я столкнулся изначально.
Я опубликовал проблему на странице Cartopy GitHub ( https://github.com/SciTools/cartopy/issues/879), где QuLogic предложил решение, позволяющее остановить ошибку сегментации, путем переустановки с использованием:
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. Надеюсь, что это имеет смысл. (См. Джейс Браунинг в OSError, geos_c не может быть найден при установке Shapely).
Итак, вот краткое изложение всего моего решения, на случай, если оно поможет кому-то другому. Любые предложения по улучшению будут приветствоваться.
Для справки, моя установка - это стандартная (не администраторская) учетная запись в Mac OS 10.11.6 (El Capitan), работающая на iMac. У меня, однако, также есть доступ к учетной записи администратора при необходимости.
Установленная версия Python 3.6 с использованием установщика, предоставленного на python.org
В качестве администратора использовал fink для установки gdal2, gdal2-dev, libproj9, libgeos3.6.1. (Также использовал fink для установки версии python3.6, gdal-py36, freetype, freetype219, cairo, gsl, sqlite3 и libspatialite7, но не уверен, что эти пакеты абсолютно необходимы.)
Python 3.6 был установлен в /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6. Создал виртуальную среду (называемую venv36) с помощью -m venv следующим образом:
В командной строке:
$ 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
- Активировал виртуальную среду и установил pip необходимые пакеты. Пакеты 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
- Наконец, добавлена символическая ссылка в /opt/local/lib/ (где cartopy - или какой-то другой пакет - настаивает на поиске libgeos), которая указывает на библиотеку libgeos, установленную fink (называемую 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. Убедитесь, что первая строка содержит следующее, если вы хотите, чтобы карты были нарисованы в блокноте:
%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)
) но, надо надеяться, все равно получится следующее изображение:
Итак, это все. Надеюсь, поможет. Любые комментарии или предложения по улучшению будут оценены.
Я напишу свой опыт с этой проблемой здесь, надеясь, что это кому-нибудь поможет.
Как мне удалось установить Cartopy
на MacOS:
У меня MacOS 10.12.6, использующий virtualenv
с Python 3.7.0 (поэтому я не использую conda
).
Следуя требованиям, установите необходимые библиотеки Python, если у вас их еще нет:
pip install numpy pip install Cython pip install --no-binary :all: shapely pip install pyshp pip install six
Получение следующих версий в моем случае:
numpy==1.15.3 Cython==0.29 Shapely==1.6.4.post2 pyshp==2.0.1 six==1.11.0
Также я
brew
установлены:brew install proj brew install geos
Получение версий:
proj --> Rel. 5.2.0, September 15th, 2018 geos-config --version --> 3.7.0
Также добавьте
export GEOS_DIR=/usr/local/Cellar/geos/3.7.0/
к моему~/.bash_profile
,В заключение,
pip
устанавливать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, чтобы игнорировать двоичные колеса.
Вывод: я считаю, что это должно быть включено где-то в Cartopy
инструкция по установке для пользователей Mac.
Как уже user1718097, существует проблема в Cartopy
Репозиторий GitHub с этой информацией.