J'essaie de construire une fonction simple qui prend une instance de sous-intrigue (matplotlib.axes._subplots.AxesSubplot
) Et transforme sa projection en une autre projection, par exemple, en l'une des projections cartopy.crs.CRS
.
L'idée ressemble à ceci
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)
Bien sûr, je peux simplement utiliser la fonction 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()
mais je me demandais s'il y avait une méthode matplotlib
appropriée pour changer une projection d'axe de sous-intrigue après elle a été définie. La lecture de l'API matplotlib n'a malheureusement pas aidé.
Vous ne pouvez pas modifier la projection d'un axe existant, la raison est donnée ci-dessous. Cependant, la solution à votre problème sous-jacent consiste simplement à utiliser l'argument subplot_kw
Pour plt.subplots()
décrit dans la documentation de matplotlib ici . Par exemple, si vous vouliez que toutes vos sous-parcelles aient la projection cartopy.crs.PlateCarree
Que vous pourriez faire
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()})
Concernant la question réelle, spécifier une projection lorsque vous créez un ensemble d'axes détermine la classe d'axes que vous obtenez, qui est différente pour chaque type de projection. Par exemple
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))
Ce code imprimera ce qui suit
<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.PolarAxesSubplot'>
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'>
Remarquez comment chaque axe est en fait une instance d'une classe différente.
suite à la réponse à cette question:
J'ai trouvé un hack pour changer la projection d'une hache après l'avoir créée, ce qui semble fonctionner au moins dans l'exemple simple ci-dessous, mais je ne sais pas si cette solution est la meilleure façon
from matplotlib.axes import Axes
from matplotlib.projections import register_projection
class CustomAxe(Axes):
name = 'customaxe'
def plotko(self, x):
self.plot(x, 'ko')
self.set_title('CustomAxe')
register_projection(CustomAxe)
if __name__ == '__main__':
import matplotlib.pyplot as plt
fig = plt.figure()
## use this syntax to create a customaxe directly
# ax = fig.add_subplot(111, projection="customaxe")
## change the projection after creation
ax = plt.gca()
ax.__class__ = CustomAxe
ax.plotko(range(10))
plt.show()