Why does subplot_kws projection hides the lat and lon?

87 Views Asked by At

With a xarray dataset, how can I use FacetGrid with a specific cartopy projection and keep the latitude and longitude values along the axis?

I was trying to use faceting as described in the user-guide here. As soon as I try to give the subplots a specific projection, I lose the lat and lon values on the axis

here is an example:

import xarray as xr
import cartopy.crs as ccrs

airtemps = xr.tutorial.open_dataset("air_temperature")
air = airtemps.air - 273.15
t = air.isel(time=slice(0, 365 * 4, 250) )
g_simple = t.plot.contourf(x="lon", y="lat", col="time", col_wrap=3,
                           transform = ccrs.PlateCarree(),
                           subplot_kws={"projection": ccrs.PlateCarree()},
                           levels=51,
)

enter image description here

but if I comment out the projection line

import xarray as xr
import cartopy.crs as ccrs

airtemps = xr.tutorial.open_dataset("air_temperature")
air = airtemps.air - 273.15
t = air.isel(time=slice(0, 365 * 4, 250) )
g_simple = t.plot.contourf(x="lon", y="lat", col="time", col_wrap=3,
                           #  subplot_kws={"projection": ccrs.PlateCarree()},
                           levels=51,
)

enter image description here

Why does it happen? and how can i fix this?

1

There are 1 best solutions below

5
RuthC On BEST ANSWER

Cartopy turns the axis labels off by default because they do not make sense for all of Cartopy's projections. You can turn them on again by using the set_visible method on each axis. I also here added coastlines because I think it helps make it obvious where we are looking.

It seems that xarray is using tight_layout underneath somewhere. I couldn't figure out how to make space for the labels and keep the colorbar in the right place with tight_layout so I switched to using the more modern compressed layout. It turns out you can't switch the layout engine in this way if you already have a colorbar, so I turned the colorbar off initially in the call to contour and added back after switching layout engines.

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

airtemps = xr.tutorial.open_dataset("air_temperature")
air = airtemps.air - 273.15
t = air.isel(time=slice(0, 365 * 4, 250) )
g_simple = t.plot.contourf(x="lon", y="lat", col="time", col_wrap=3,
                           transform = ccrs.PlateCarree(),
                           subplot_kws={"projection": ccrs.PlateCarree()},
                           levels=51, add_colorbar=False
)

for ax in g_simple.axs.flat:  # loop through the map axes
    subplotspec = ax.get_subplotspec()
    if subplotspec.is_last_row():
        ax.xaxis.set_visible(True)
    if subplotspec.is_first_col():
        ax.yaxis.set_visible(True)
    ax.coastlines()
    
g_simple.fig.set_layout_engine("compressed")
g_simple.fig.get_layout_engine().set(h_pad=0.2)  # More vertical space between maps
g_simple.add_colorbar()

plt.show()

[image upload seems to be currently broken across StackOverflow]