Korrekte Platzierung des Farbbalkens relativ zu den Geo-Achsen (Cartopy)
Mit Cartopy möchte ich die volle Kontrolle darüber haben, wohin meine Farbleiste geht. Normalerweise erhalte ich dazu die aktuelle Achsenposition als Basis und erstelle dann neue Achsen für die Farbleiste. Dies funktioniert gut für Standard-Matplotlib-Achsen, jedoch nicht, wenn Cartopy und geo_axes verwendet werden, da dies die Achsen verzerrt.
So ist meine Frage: Wie erhalte ich die genaue Position meiner geo_axes?
Hier ist ein Codebeispiel basierend auf den Cartopy-Dokumentenhttp: //scitools.org.uk/cartopy/docs/latest/matplotlib/advanced_plotting.htm:
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()
Resulting Figure, wenn "set_aspect" verwendet wird:
Resulting Figure, wenn "set_aspect" weggelassen wird:
Grundsätzlich möchte ich die erste Figur (korrekt platzierte Farbleiste) erhalten, aber ohne "set_aspect". Ich denke, dass dies mit einigen Transformationen möglich sein sollte, aber ich habe bisher keine Lösung gefunden.
Vielen Dank