Skip to content

Projection issue with plot.imshow and cartopy projection #1581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jbusecke opened this issue Sep 19, 2017 · 4 comments
Closed

Projection issue with plot.imshow and cartopy projection #1581

jbusecke opened this issue Sep 19, 2017 · 4 comments

Comments

@jbusecke
Copy link
Contributor

jbusecke commented Sep 19, 2017

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

@fmaussion
Copy link
Member

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.

@fmaussion
Copy link
Member

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

@jbusecke
Copy link
Contributor Author

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

@dcherian
Copy link
Contributor

dcherian commented Mar 7, 2019

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.

@dcherian dcherian closed this as completed Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants