Проблемы с проекцией при отображении изображения на карте с помощью Cartopy

У меня есть некоторые данные спутникового изображения, которые я хотел бы отобразить с помощью Cartopy. Я успешно выполнил пример изображения, подробно описанный здесь. В результате получается этот код:

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

fig = plt.figure(figsize=(12, 12))
img_extent = (-77, -59, 9, 26)

ax = plt.axes(projection=ccrs.PlateCarree())
# image data coming from server, code not shown
ax.imshow(img, origin='upper', extent=img_extent)
ax.set_xmargin(0.05)
ax.set_ymargin(0.10)

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

ax.coastlines()
ax.gridlines()

plt.show() 

Этот код генерирует следующее изображение неправильная проекция

Моя проблема в том, что данные спутникового снимка находятся не в проекции PlateCarree, а в проекции Меркатора.

Но когда я получаю объект оси с

ax = plt.axes(projection=ccrs.Mercator())

Я теряю береговые линии.

без береговых линий

Я видел сообщение об ошибке здесь. Но

ax.set_global()

приводит к этому изображению:

где мои данные

Данных нет, и Сан-Диего находится не в том месте. Также изменились широта/долгота. Что я делаю неправильно?

Обновление после обсуждения

Основная проблема в том, что я неправильно указал экстенты изображения в целевой проекции с помощью метода transform_points. Я также должен был уточнить систему отсчета координат в методе imshow, как предлагает Фил. Вот правильный код:

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

proj = ccrs.Mercator()
fig = plt.figure(figsize=(12, 12))
extents = proj.transform_points(ccrs.Geodetic(),
                                np.array([-77, -59]),
                                np.array([9, 26]))

img_extents = (extents[0][0], extents[1][0], extents[0][6], extents[1][7] ) 

ax = plt.axes(projection=proj)
# image data coming from server, code not shown
ax.imshow(img, origin='upper', extent=img_extents,transform=proj)

ax.set_xmargin(0.05)
ax.set_ymargin(0.10)

# 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())

ax.coastlines()
ax.gridlines()

plt.show() 

В результате получается правильно геопроецированное спутниковое изображение:

правильное изображение


person Julien Chastang    schedule 10.09.2013    source источник
comment
Мой Cartopy 0.7 сломался после обновления до Mpl 1.3, поэтому я не могу проверить его для вас. Но разве вы не должны указывать координаты данных, которые вы рисуете? Если вы этого не сделаете, я думаю, что координаты считаются равными проекции осей. Поэтому попробуйте добавить transform=ccrs.PlateCarree() к своим командам построения графика.   -  person Rutger Kassies    schedule 11.09.2013


Ответы (1)


В идеале, старайтесь всегда указывать конкретную систему отсчета координат, в которой находятся ваши данные, при построении графика с помощью картопии (через ключевое слово transform). Это будет означать, что вы можете просто переключать проекции в своем скрипте, и данные будут автоматически помещаться в нужное место.

Таким образом, в вашем случае plt.imshow должен иметь аргумент ключевого слова transform=ccrs.Mercator() (вам может понадобиться более конкретный параметризованный экземпляр Mercator). Если ваши экстенты указаны в геодезических (широта и долгота), вам придется преобразовать ограничивающую рамку в координаты Меркатора, но кроме этого все остальное должно работать как положено.

ПРИМЕЧАНИЕ. Я собираюсь обновить пример до включите аргумент преобразования ;-) (PR: https://github.com/SciTools/cartopy/pull/343)

ХТН

person pelson    schedule 11.09.2013
comment
Спасибо, я добавил сообщение об обновлении обсуждения с правильным кодом. - person Julien Chastang; 11.09.2013
comment
Здорово. Рад, что это помогло. Хороший сюжет :-) - person pelson; 12.09.2013