1

I try to make subplot maps with Cartopy using data from xarray tutorial and increase each map in vertical size, but failed. Also making colorbar at each specific subplots.

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import xarray as xr
import numpy as np
import matplotlib.ticker as mticker
# Load available datasets
ds=xr.tutorial.load_dataset("air_temperature")
# Get 6 maps (images)
air=[ds.air.isel(time=i) for i in range(7)]
# Specify crs
proj = ccrs.PlateCarree() #ccrs.Orthographic()
# Set size and number of plots
fig,axes = plt.subplots(ncols=3,nrows=2,figsize=(20,7),
                      subplot_kw={'projection': proj},gridspec_kw = {'wspace':0.2, 'hspace':0.007})

# Zip maps and axes and index
mzip=zip(air,[y for x in axes for y in x],[i for i in range(len(air))])
# Loop over the maps and axes
for img, ax,idx in mzip:
        # Add countries
    ax.add_feature(cfeature.BORDERS, facecolor="green")
    # plot maps/images
    temp=img.plot.contourf(ax=ax,transform=proj,cmap="magma",vmax=300,vmin=220, add_colorbar=False)
    # Create gridlines
    gl = ax.gridlines(crs=proj, linewidth=1, color='black', alpha=0.2, linestyle="--")
    # Manipulate gridlines number and spaces
    gl.ylocator = mticker.FixedLocator(np.arange(-90,90,20))
    gl.xlocator = mticker.FixedLocator(np.arange(-180, 180, 25)) 
    gl.xlabels_top = False
    gl.xlabels_bottom = True
    gl.ylabels_left = True
    gl.ylabels_right = False
    # Add colorbar at specific indices (specific 3,4,5)
    if idx==3:
        cbar_ticks = np.arange(224, 320, 15) # min and max values of the colorbar
        cbar = plt.colorbar(temp,
                        orientation='horizontal',
                        shrink=0.9,
                        pad=0.073,
                        extendrect=True,ticks=cbar_ticks,label="Air Temperature") # ticks=cbar_ticks
    elif idx==4:
        cbar_ticks = np.arange(224, 320, 15) # min and max values of the colorbar
        cbar = plt.colorbar(temp,
                        orientation='horizontal',
                        shrink=0.9,
                        pad=0.073,
                        extendrect=True,ticks=cbar_ticks,label="Air Temperature") # ticks=cbar_ticks
    elif idx==5:
        cbar_ticks = np.arange(224, 320, 15) # min and max values of the colorbar
        cbar = plt.colorbar(temp,
                        orientation='horizontal',
                        shrink=0.9,
                        pad=0.073,
                        extendrect=True,ticks=cbar_ticks,label="Air Temperature") 

plt.show()

enter image description here

1 Answer 1

1

I can't execute your code due to lack of data so here's a general example on how you could do it (using an explicit GridSpec instead of plt.subplots:

  1. in order to add a colorbar for each individual subplot, you'd need to specify the axis on which to draw the colorbar

  2. concerning the vertical size... that very much depends on the extent of your data (since usually you don't want to distort the plot, the only option is to increase the plot-extent or use another projection)

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from cartopy import crs as ccrs

gs = GridSpec(3, 3, height_ratios=(1, 1, 0.1))
gs.update(top=.95, bottom=0.05, left=0.05, right=.95, hspace=0, wspace=0.2)


f = plt.figure(figsize=(12,8))

# initialize the cartopy-axes
axes_top = [f.add_subplot(g, projection=ccrs.PlateCarree()) for g in (gs[0,0], gs[0,1], gs[0,2])]
axes_bottom = [f.add_subplot(g, projection=ccrs.PlateCarree()) for g in (gs[1,0], gs[1,1], gs[1,2])]
# initialize the colorbar-axes
cb_axes = [f.add_subplot(g) for g in (gs[2,0], gs[2,1], gs[2,2])]


# plot stuff and add colorbars
for ax in axes_top:
    ax.coastlines()
    s = ax.scatter(range(50, 75), range(50, 75), c=range(0, 25),
                   vmin=0, vmax=80)
    
for ax, c_ax in zip(axes_bottom, cb_axes):
    ax.coastlines()
    s = ax.scatter(range(50, 80), range(50, 80), c=range(50, 80),
                   vmin=0, vmax=80)
    
    plt.colorbar(s, cax=c_ax, orientation="horizontal")

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.