I am working with ocean variables of the LENS2 ensemble of CESM2 and am now trying to plot the data on a geographical grid. The ocean model POP2 is based on a displaced-pole grid with poles in Greenland and Antarctica. The netCDF file contains the related WGS84 latitudes and longitudes but I do not manage to plot the data, especially north of 60 degree North.
I am conducting most of my work with xarray and would like to stay within this library, but if necessary I am also prepared to switch to other tools.
Ideally I would like to still be able to see the original grid cells instead of having the code interpolated. (Interpolation with plt.contour() works if I plot data below 60 degrees North. However, I need to plot data within the Nordic Seas and there the plot collapses.)
To show the problem, here is the simplest case:
field = ds_temp.TEMP.isel(time=0, z_t=0)
extent = (ds_temp.TLONG.min(), ds_temp.TLONG.max(),
ds_temp.TLAT.min(), ds_temp.TLAT.max())
fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.PlateCarree())
cs = ax.imshow(field, extent=extent,
origin='lower',
transform=ccrs.PlateCarree())
ax.coastlines()
plt.show()
This results in the following plot:

As you can see the cartopy coastlines and the data’s land mask are shifted. How can I plot my data with cartopy and if possible staying with xarray functions?
Instead of calling
ax.coastlines()you could try to draw your own coastlines around continents appearing as white areas on the map. Most likely, your orginal data infieldhas some invalid values for mainland areas of the map. If you print it, it could probably look something like this:Those double dashes look like missing data in masked arrays. So one way to plot coastlines could be using matplotlib.pyplot.contour with a slightly modified data, where those "missing values" are replaced with some other ones, allowing you to compare them against a suitable threshold for drawing contours:
The code above is based on this example, showing the data with matplotlib.pyplot.contourf, and resulting in the following picture:
It doesn't look particularly nice, but it seems to do what you want. You will need to choose a suitable projection. If you use
imshow()for plotting the original data, then you may need to adjust theextentparameters inimshow()andcontour()separately.