'align a cartopy 2D map plot with a 1D line plot

I need to align a cartopy 2D map subplot with a 1D line subplot, using the following code:

import xarray as xr
import cartopy.crs as ccrs
import matplotlib.pyplot as plt


air = xr.tutorial.open_dataset('air_temperature').air[0]

fig = plt.figure(figsize=(14,5))

ax1 = fig.add_subplot(121,
                 projection=ccrs.PlateCarree(central_longitude=180))
air.plot.pcolormesh(ax=ax1,
               transform=ccrs.PlateCarree(),
               cbar_kwargs={'orientation':'horizontal'})
ax1.coastlines()
ax1.set_extent((air.lon[0], air.lon[-1], air.lat[-1], air.lat[0]),
               crs=ccrs.PlateCarree())

ax2 = fig.add_subplot(122)
air.mean('lon').plot(ax=ax2, y='lat')

plt.tight_layout()

This gives the plot as: plot

Both subplots have the same y- (latitude-) range and I expect the boxes of the two axes could align with each other. Is there a simple way to do this?



Solution 1:[1]

I found a nice solution from proplot:

import xarray as xr
import proplot as plot

air = xr.tutorial.open_dataset('air_temperature').air[0]

array = [
    [1, 1, 1, 2],
    [1, 1, 1, 2],
    [3, 3, 3, 0]
]

fig, ax = plot.subplots(array, proj={1:'pcarree'}, width=7)

air.plot(ax=ax[0], add_colorbar=False)
air.mean('lon').plot(ax=ax[1], y='lat', xincrease=True)
air.mean('lat').plot(ax=ax[2])

ax.format(abc=True, abcloc='l', abcstyle='(a)')

ax[0].format(lonlim=(air.lon[0], air.lon[-1]), latlim=(air.lat[0], air.lat[-1]),
             coast=True, labels=True, lonlines=20, latlines=10,
             title='temperature')
ax[1].set(title='zonal mean', xlim=[240, 300], ylabel=None,
          yticks=[20, 30, 40, 50, 60, 70],
          yticklabels=['20°N','30°N','40°N','50°N','60°N','70°N'])
ax[2].set(title='meridional mean', ylim=[260, 285],
          ylabel=None, xlabel='longitude',
          xticklabels=['160°W','140°W','120°W','100°W','80°W','60°W','40°W'])

which gives this plot:

the plot

However, adding ylabel='latitude (N)' for panel a is still problematic. But it is good enough for me.

Solution 2:[2]

I am totally new to proplot, but I just found it only works when we assign 1 to GeoAxes. For instance:

import proplot as pplt
import cartopy.crs as ccrs
fig, (m_ax,l_ax,r_ax) = pplt.subplots([2,1,3], proj={1:ccrs.PlateCarree()}, width=12) # m_ax=axs[0], l_ax=axs[1], and r_ax=axs[2]
l_ax.plot([1,2,3])
m_ax.format(coast=True, labels=True)
r_ax.plot([1,2,3])

enter image description here

fig, (l_ax,m_ax,r_ax) = pplt.subplots([1,2,3], proj={2:ccrs.PlateCarree()}, width=12)
l_ax.plot([1,2,3])
m_ax.format(coast=True, labels=True)
r_ax.plot([1,2,3])

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MiniUFO
Solution 2