Как изменить проекцию подмножества matplotlib на существующую ось?


Я пытаюсь построить простую функцию, которая берет экземпляр подзаголовка (matplotlib.axes._subplots.AxesSubplot) и преобразует его проекцию в другую проекцию, например, в одну из проекций cartopy.crs.CRS.

Идея выглядит примерно так

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

def make_ax_map(ax, projection=ccrs.PlateCarree()):
    # set ax projection to the specified projection
    ...
    # other fancy formatting
    ax2.coastlines()
    ...

# Create a grid of plots
fig, (ax1, ax2) = plt.subplots(ncols=2)
# the first subplot remains unchanged
ax1.plot(np.random.rand(10))
# the second one gets another projection
make_ax_map(ax2)

Конечно, я могу просто использовать функцию fig.add_subplot():

fig = plt.figure(figsize=(10,5))
ax1 = fig.add_subplot(121)
ax1.plot(np.random.rand(10))

ax2 = fig.add_subplot(122,projection=ccrs.PlateCarree())
ax2.coastlines()
Но мне было интересно, существует ли правильный метод matplotlib для изменения проекции оси подзаголовка После того, как она была определена. Чтение matplotlib API, к сожалению, не помогло.
1 17

1 ответ:

Вы не можете изменить проекцию существующей оси, причина приведена ниже. Однако решение вашей основной проблемы состоит в том, чтобы просто использовать аргумент subplot_kw для plt.subplots(), описанный в документации matplotlib здесь. Например, если вы хотите, чтобы все ваши подзаголовки имели проекцию cartopy.crs.PlateCarree, Вы можете сделать

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

# Create a grid of plots
fig, (ax1, ax2) = plt.subplots(ncols=2, subplot_kw={'projection': ccrs.PlateCarree()})

Что касается фактического вопроса, указание проекции при создании набора осей определяет класс осей, который вы получаете, который отличается для каждого тип проекции. Например

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

ax1 = plt.subplot(311)
ax2 = plt.subplot(312, projection='polar')
ax3 = plt.subplot(313, projection=ccrs.PlateCarree())

print(type(ax1))
print(type(ax2))
print(type(ax3))

Этот код выведет следующее

<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>
Обратите внимание, что каждая ось на самом деле является экземпляром другого класса.