Utilizzando Cartopy, mi piacerebbe avere il controllo completo su dove va la mia barra colori. Di solito lo faccio posizionando gli assi correnti come base e quindi creando nuovi assi per la barra dei colori. Funziona bene per assi standard matplotlib ma non quando si utilizza Cartopy e geo_axes, perché ciò distorce gli assi.Posizionamento corretto della barra dei colori relativa agli assi geografici (cartopy)
Quindi, la mia domanda è: come ottengo la posizione esatta dei miei geo_axes?
Ecco un esempio di codice in base ai documenti Cartopy http://scitools.org.uk/cartopy/docs/latest/matplotlib/advanced_plotting.html:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import os
from netCDF4 import Dataset as netcdf_dataset
from cartopy import config
def main():
fname = os.path.join(config["repo_data_dir"],
'netcdf', 'HadISST1_SST_update.nc'
)
dataset = netcdf_dataset(fname)
sst = dataset.variables['sst'][0, :, :]
lats = dataset.variables['lat'][:]
lons = dataset.variables['lon'][:]
#my preferred way of creating plots (even if it is only one plot)
ef, ax = plt.subplots(1,1,figsize=(10,5),subplot_kw={'projection': ccrs.PlateCarree()})
ef.subplots_adjust(hspace=0,wspace=0,top=0.925,left=0.1)
#get size and extent of axes:
axpos = ax.get_position()
pos_x = axpos.x0+axpos.width + 0.01# + 0.25*axpos.width
pos_y = axpos.y0
cax_width = 0.04
cax_height = axpos.height
#create new axes where the colorbar should go.
#it should be next to the original axes and have the same height!
pos_cax = ef.add_axes([pos_x,pos_y,cax_width,cax_height])
im = ax.contourf(lons, lats, sst, 60, transform=ccrs.PlateCarree())
ax.coastlines()
plt.colorbar(im, cax=pos_cax)
ax.coastlines(resolution='110m')
ax.gridlines()
ax.set_extent([-20, 60, 33, 63])
#when using this line the positioning of the colorbar is correct,
#but the image gets distorted.
#when omitting this line, the positioning of the colorbar is wrong,
#but the image is well represented (not distorted).
ax.set_aspect('auto', adjustable=None)
plt.savefig('sst_aspect.png')
plt.close()
if __name__ == '__main__': main()
risultanti figura, quando si utilizza "set_aspect":
risultante figura, quando omettendo "set_aspect":
Fondamentalmente, mi piacerebbe ottenere la prima cifra (colorbar posizionata correttamente) ma senza usare "set_aspect". Immagino che questo dovrebbe essere possibile con alcune trasformazioni, ma non ho trovato una soluzione finora.
Grazie!
Ottima risposta! Non avrei mai trovato questa soluzione da sola! – user3497890
Forse una breve domanda se posso: È possibile inserire la definizione di resize_colorbar da qualche altra parte e passare axe e cbar_ax come argomenti (in modo che questa funzione diventi riutilizzabile)? Aggiornamento – user3497890
: mentre plt.show() fornisce il risultato corretto, plt.savefig ('sst.png') no (la barra colorata rimane nella posizione originale in [0,0,0,1,0,1]). Ho cercato di cambiare il back-end in matplotlib.use ('Agg'), ma questo non aiuta. Qualche idea su come potrei farlo funzionare con savefig? – user3497890