Xarray: Projection issue with plot.imshow and cartopy projection

Created on 19 Sep 2017  路  4Comments  路  Source: pydata/xarray

I am experiencing some trouble when using cartopy transformations in the plot module.
I am concerned about plotting speed (plotting very high resolution maps of ocean model output takes forever).
According to #657 I tried to use plot.imshow but I am getting unexpected results for the map projection.
The longitude wrapping does not seem to work and as seen by the mismatch between the ocean mask data and the coastline in the example below, the projection seems to be inaccurate.

This seems to be related to the cartopy module (see the last plot which was done 'outside' of xarray).

My question is twofold, I guess

1) Is there is any other 'high speed' alternative to plot high resolution maps.
2) Since this error might not appear as drastically in all mapping scenarios, should plot.imshow display a warning, when invoked with a transformation argument, or even an error?

import xarray as xr
%matplotlib inline
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

ds = xr.open_dataset('ocean_mask.nc')

plt.figure()
ax_i = plt.gca(projection=ccrs.Robinson())
ds.wet.plot.imshow(x='lonh',y='lath',ax=ax_i,transform=ccrs.PlateCarree())
ax_i.coastlines()
plt.title('imshow')

plt.figure()
ax_p = plt.gca(projection=ccrs.Robinson())
ds.wet.plot(x='lonh',y='lath',ax=ax_p,transform=ccrs.PlateCarree())
ax_p.coastlines()
plt.title('standard plot')

plt.figure()
ax = plt.gca(projection=ccrs.Robinson())

ax.imshow(ds.wet.data,
          transform=ccrs.PlateCarree(),
          extent=[ds.lonh.min().data, ds.lonh.max().data,ds.lath.min().data, ds.lath.max().data])
ax.coastlines()
plt.title('cartopy imshow')

download-2
download-1
download

ocean_mask.nc.zip

documentation help wanted

All 4 comments

Thanks for the detailed and well documented question. I had a look at your data, and there are two issues that imshow cannot handle well:

  • your data isn't well centred (lons go from -300 to 60, which explains the shape of your image on the globe). This wouldn't be a big deal if it wasn't for the other problem, which is:
  • your latitude data isn't regular.
plt.plot(ds.lath[1:].values - ds.lath[:-1].values)

Gives:

index

which is quite... interesting.

Anyways, imshow is so much faster because it needs regular, nicely sorted data. In your case I don't think there is much other choice than pcolormesh or contourf... Note also that plotting on Robinson is slower than plotting on a plate carree projection.

Regarding your comment about the doc: maybe it would be useful to specify somewhere that imshow will work only for regularly spaced data indeed.

Thank you very much @fmaussion. And that is indeed interesting. I have just started to work with this, so I appreciate the pointer!

maybe it would be useful to specify somewhere that imshow will work only for regularly spaced data indeed.

Current docstring for imshow does specify this. Closing.

Was this page helpful?
0 / 5 - 0 ratings