Карты

Раньше для построения карт использовался модуль basemappip, но он устарел и более не поддерживается. На замену ему пришел модуль cartopypip. Установка пакета cartopy в Windows из pip вызывает сложности, поэтому вот готовые пакеты для разных версий Python:

Для выбора нужной проекции используем документацию.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from cartopy import crs as ccrs

fig = plt.figure()

ax = fig.add_subplot(projection=ccrs.PlateCarree())

ax.set_extent([-6, 3, 48, 58], crs=ccrs.PlateCarree())

gl = ax.gridlines(draw_labels=True)
gl.xlocator = mticker.FixedLocator(np.arange(-6.0,3.0,2.0))
gl.ylocator = mticker.FixedLocator(np.arange(48.0,58.0,2.0))

ax.scatter([-2],[52], transform=ccrs.PlateCarree())

ax.coastlines(resolution='50m')

Рисование данных поверх карты выполняется обычными методами, например plot с добавлением параметра transform если координаты указаны, как долгота и широта в градусах.

Пример карты построенной в cartopy

Картографические данные Natural Earth

Картографические данные cartopy берет из проекта Natural Earth.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from cartopy import crs as ccrs
import cartopy.feature

#%%

fig = plt.figure()

ax = fig.add_subplot(projection=ccrs.PlateCarree())

ax.set_extent([-6, 3, 38, 48], crs=ccrs.PlateCarree())

gl = ax.gridlines(draw_labels=True)
gl.xlocator = mticker.FixedLocator(np.arange(-6.0,3.0,2.0))
gl.ylocator = mticker.FixedLocator(np.arange(38.0,48.0,2.0))

resol = '50m' # еще есть '110m' - самая грубая версия и '10m' - самая точная версия
bodr = cartopy.feature.NaturalEarthFeature(category='cultural', 
    name='admin_0_boundary_lines_land', scale=resol, facecolor='none', alpha=0.7)
land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
    scale=resol, edgecolor='k', facecolor=cartopy.feature.COLORS['land'])
ocean = cartopy.feature.NaturalEarthFeature('physical', 'ocean', \
    scale=resol, edgecolor='none', facecolor=cartopy.feature.COLORS['water'])
lakes = cartopy.feature.NaturalEarthFeature('physical', 'lakes', \
    scale=resol, edgecolor='b', facecolor=cartopy.feature.COLORS['water'])
rivers = cartopy.feature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', \
    scale=resol, edgecolor='b', facecolor='none')

ax.add_feature(land)
ax.add_feature(ocean)
ax.add_feature(lakes)
ax.add_feature(rivers)
ax.add_feature(bodr, linestyle='--', alpha=1)

Какие именно картографические данные доступны см. по ссылке https://github.com/nvkelso/natural-earth-vector в наборах cultural и physical. Карты автоматически скачиваются по мере надобности, при этом в консоль выводится предупреждение DownloadWarning.

Пример карты построенной в cartopy

Использование Tile-серверов в cartopy

from cartopy.io.img_tiles import GoogleWTS, OSM, GoogleTiles


class ArcGISWSR(GoogleWTS):
    def _image_url(self, tile):
        x, y, z = tile
        return f'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}.jpg'


tiles_provider = OSM()
#tiles_provider = GoogleTiles()
#tiles_provider = GoogleTiles()

plt.figure(figsize=(16, 16))

ax = plt.axes(projection=tiles_provider.crs)

ax.set_extent([-6, 3, 38, 48], ccrs.PlateCarree())

ax.add_image(tiles_provider, 6)

plt.show()

Пример карты построенной в cartopy

Некоторые приемы работы с cartopy

# Скрытие части подписей по осям:
gridlines = ax.gridlines(draw_labels=True)
gridlines.top_labels = False
gridlines.right_labels = False

# Добавление теплокарты:
im = ax.imshow(data,  origin='upper', extent =[lon[0], lon[-1], lat[-1], lat[0]], transform=ccrs.PlateCarree(), cmap = cmap) 
fig.colorbar(im, ax=ax)

#Добавление точки с подписью:
ax.scatter([50.8667],[61.6667], transform=ccrs.PlateCarree())

mpl_trans = ccrs.PlateCarree()._as_mpl_transform(ax)
ax.annotate('SYKTYVKAR',(50.8667,61.6667), xycoords=mpl_trans)

Построение карт из NetCDF файлов

Пример NetCDF файла

import netCDF4 as nc
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from cartopy import crs as ccrs

# Добавляем encoding если 1. в Windows и  2. в пути к файлу есть русские буквы (и другие символы Unicode)
ds = nc.Dataset("file.nc", encoding="cp1251") 

print(ds) # обзор структуры NetCDF файла

data = ds['varname'][57,:,:] # получаем нужный срез нужной переменной

#Задаем экстент по границам данных в файле
ax.set_extent([ds['lon'][0], ds['lon'][-1], ds['lat'][0], ds['lat'][-1]], crs=ccrs.PlateCarree())