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,
)
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,
)
Why does it happen? and how can i fix this?
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()