2015-11-26 12 views
11

Sto provando a costruire una semplice funzione che prende un'istanza di sottotrama (matplotlib.axes._subplots.AxesSubplot) e trasforma la sua proiezione in un'altra proiezione, ad esempio, in una delle proiezioni cartopy.crs.CRS.Come cambio la proiezione sottotrama di matplotlib di un asse esistente?

L'idea simile a questa

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) 

Naturalmente, posso solo usare fig.add_subplot() funzione:

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

ma mi chiedevo se esiste un adeguato metodo di matplotlib di cambiare un asse sottotrama proiezione dopo è stata definita. La lettura dell'API matplotlib non è stata di aiuto, purtroppo.

risposta

14

Non è possibile modificare la proiezione di un asse esistente, il motivo è indicato di seguito. Tuttavia, la soluzione al problema sottostante è semplicemente utilizzare l'argomento subplot_kw su plt.subplots() descritto nella documentazione matplotlib here. Ad esempio, se si voleva tutte le sottotrame di avere la cartopy.crs.PlateCarree di proiezione che si potrebbe fare

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

Per quanto riguarda la domanda effettiva, specificando una proiezione quando si crea un set di assi determina la classe assi si ottiene, che è diverso per ogni tipo di proiezione. Ad esempio

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

Questo codice stamperà il seguente

<class 'matplotlib.axes._subplots.AxesSubplot'> 
<class 'matplotlib.axes._subplots.PolarAxesSubplot'> 
<class 'cartopy.mpl.geoaxes.GeoAxesSubplot'> 

noti come ciascun asse è in realtà un'istanza di una classe diversa.

+3

Grazie! E solo per confermare, la parola chiave 'projection' determina la classe per tutte le sottotrototteri in una volta, quindi non c'è modo di passare diverse proiezioni in' subplot_kw'? E.g. 'projection = 'polar'' per la prima colonna e' projection = ccrs.PlateCarree() 'per la seconda colonna di un set di subplot creato da' plt.subplots (ncols = 2) '? –

+0

Le parole chiave in 'subplot_kw' vengono passate a ciascun asse, quindi non penso che tu possa fare ciò che descrivi. La funzione 'subplots' è un comodo wrapper per soddisfare il caso d'uso di base, se hai bisogno di qualcosa in più puoi scrivere la tua funzione wrapper usando' add_subplot' o simile. – ajdawson

+0

C'è un modo per farlo con ImageGrid? Sarebbe bello poter avere il controllo sulla spaziatura della mappa e il posizionamento della barra di colore che consente ImageGrid, ma non vedo un modo per impostare la proiezione per le sottotrame nella griglia. –

Problemi correlati