Search code examples
python-3.xmatplotlibcartopy

Customize multiple subplots with cartopy in Python


I try to customize plots in longer vertical size with subplots using cartopy, but still can't figure out how to increase height of each plots (vertical height).

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])
# Loop over the maps and axes
for img, ax 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

plt.show()

enter image description here


Solution

  • You can add the aspect keyword when creating the subplots. But as Jody Klymak already alluded to, perhaps it would be better to choose a different projection?

    But adding for example: subplot_kw={'projection': proj, "aspect": 2}

    I've slightly changed your example:

    ds = xr.tutorial.load_dataset("air_temperature")
    air = [ds.air.isel(time=i) for i in range(7)]
    
    proj = ccrs.PlateCarree()
    fig,axes = plt.subplots(
        2, 3, figsize=(9, 6), sharex=True, sharey=True,
        subplot_kw={'projection': proj, "aspect": 2},
        gridspec_kw = {'wspace':0.2, 'hspace':0.007},
    )
    
    for i, (img, ax) in enumerate(zip(air,[y for x in axes for y in x])):
    
        temp = img.plot.contourf(
            ax=ax, transform=proj, cmap="magma",
            vmax=300,vmin=220, add_colorbar=False,
        )
        ax.set_title(img.time.to_dict()["data"])
        ax.add_feature(cfeature.BORDERS, facecolor="green")
        
        gl = ax.gridlines(crs=proj, linewidth=1, color='black', alpha=0.2, linestyle="--")
    
        gl.ylocator = mticker.FixedLocator(np.arange(-90,90,20))
        gl.xlocator = mticker.FixedLocator(np.arange(-180, 180, 25))
        
        if i>2:
            gl.bottom_labels = True
        if i == 0 or i == 3:
            gl.left_labels = True
    

    Results in:

    enter image description here