-
Notifications
You must be signed in to change notification settings - Fork 392
Description
Description
In some cases, pcolor raises a ValueError and crashes when plotting data from one projection to an other.
In the following plots, the data in the original grid are also plotted as a scatter plot at the cells centers.
The two plots at the bottoms of the figures show the original grid plotted in the original projection (PlateCarree) with pcolormesh and pcolor.
I caught the error and removed the artists crashing the plot using the geoaxes.py version from PR #1467 and I got the following plots:

With current version of geoaxes.py (as of February 23rd 2020) we get the following plot before it crashes.

The plots with geoaxes from #1467 differ from the plots from the current version of geoaxes before the crash.
We can see from the scatter plots, that the pcolormesh plots from the current version fo geoaxes are erroneous while the pcolormesh plots from #1467 version of geoaxes fit the data.
In both geoaxes version, the pcolor plots with coords in axis projection are erroneous. It is to be expected as the cells are not wrapped when the coords are given in the axes projection. On the other hand pcolor cannot plot the data with coords in data projection without raising a ValueError.
In conclusion, the fixes in PR1467, one catching the ValueError and the other one hiding the pcolor cells in the axis projection plot, allow pcolormesh to correctly plot the data.
The ValueError in pcolor needs to be investigated.
Code to reproduce
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
proj=ccrs.LambertAzimuthalEqualArea
plt.figure(figsize=(10,5), constrained_layout=True)
lats = np.linspace(-10, 90, 12)
lons = np.linspace(-180, 180, 10)
lons, lats = np.meshgrid(lons, lats)
axproj = proj(central_latitude=-30)
xye = axproj.transform_points(ccrs.PlateCarree(), lons, lats)
xe = xye[..., 0]
ye = xye[..., 1]
z4 = lats[:-1,:-1] * (1 + 0.001 * lons[:-1,:-1])
fig = plt.figure(figsize=(12, 6.4), dpi=100)
fig.suptitle('LambertAzimuthalEqualArea central_latitude=-30 '
'ValueError exception caught in pcolor')
ax21 = plt.subplot(2, 2, 3, projection=ccrs.PlateCarree())
ax22 = plt.subplot(2, 2, 4, projection=ccrs.PlateCarree())
ax1 = plt.subplot(2, 4, 1, projection=axproj)
ax2 = plt.subplot(2, 4, 2, projection=axproj)
ax3 = plt.subplot(2, 4, 3, projection=axproj)
ax4 = plt.subplot(2, 4, 4, projection=axproj)
ax21.pcolormesh(lons, lats, z4)
ax21.set_title('pcolormesh\n plot in data projection')
ax22.pcolor(lons, lats, z4)
ax22.set_title('pcolor\n plot in data projection')
ax1.pcolormesh(lons, lats, z4, transform=ccrs.PlateCarree())
ax1.set_title('pcolormesh\n coords in data projection')
ax2.pcolormesh(xe, ye, z4)
ax2.set_title('pcolormesh\n coords in axis projection')
ax3.pcolor(xe, ye, z4)
ax3.set_title('pcolor\n coords in axis projection')
for ax in [ax21, ax22, ax1, ax2, ax3, ax4]:
ax.set_global()
ax.scatter(
np.mean(np.array([lons[:-1,:-1],lons[1:,1:]]), axis=0),
np.mean(np.array([lats[:-1,:-1],lats[1:,1:]]), axis=0),
50, z4, edgecolors='black',
transform=ccrs.PlateCarree())
ax.coastlines(linewidth=0.2)
ax4.pcolor(lons, lats, z4, transform=ccrs.PlateCarree())
ax4.set_title('pcolor\n coords in data projection\n raises a ValueError')
plt.savefig("img/crash_pcolor_caught.png",
dpi=100, pad_inches=0)
Traceback
Traceback (most recent call last):
File "[path]/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py", line 508, in _draw_idle
self.draw()
File "[path]/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
self.figure.draw(self.renderer)
File "[path]/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "[path]/lib/python3.7/site-packages/matplotlib/figure.py", line 1709, in draw
renderer, self, artists, self.suppressComposite)
File "[path]/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "[path]/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "[path2]/cartopy/mpl/geoaxes.py", line 460, in draw
inframe=inframe)
File "[path]/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "[path]/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2647, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "[path]/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "[path]/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "[path]/lib/python3.7/site-packages/matplotlib/collections.py", line 866, in draw
Collection.draw(self, renderer)
File "[path]/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "[path]/lib/python3.7/site-packages/matplotlib/collections.py", line 257, in draw
transform, transOffset, offsets, paths = self._prepare_points()
File "[path]/lib/python3.7/site-packages/matplotlib/collections.py", line 235, in _prepare_points
for path in paths]
File "[path]/lib/python3.7/site-packages/matplotlib/collections.py", line 235, in <listcomp>
for path in paths]
File "[path]/lib/python3.7/site-packages/matplotlib/transforms.py", line 2390, in transform_path_non_affine
return self._a.transform_path_non_affine(path)
File "[path2]/cartopy/mpl/geoaxes.py", line 211, in transform_path_non_affine
geom, self.source_projection)
File "[path2]/cartopy/crs.py", line 221, in project_geometry
return getattr(self, method_name)(geometry, src_crs)
File "[path2]/cartopy/crs.py", line 376, in _project_polygon
return self._rings_to_multi_polygon(rings, is_ccw)
File "[path2]/cartopy/crs.py", line 626, in _rings_to_multi_polygon
multi_poly = sgeom.MultiPolygon(polygon_bits)
File "[path]/lib/python3.7/site-packages/shapely/geometry/multipolygon.py", line 62, in __init__
self._geom, self._ndim = geos_multipolygon_from_polygons(polygons)
File "[path]/lib/python3.7/site-packages/shapely/geometry/multipolygon.py", line 197, in geos_multipolygon_from_polygons
geom, ndims = polygon.geos_polygon_from_py(shell, holes)
File "[path]/lib/python3.7/site-packages/shapely/geometry/polygon.py", line 509, in geos_polygon_from_py
ret = geos_linearring_from_py(shell)
File "shapely/speedups/_speedups.pyx", line 251, in shapely.speedups._speedups.geos_linearring_from_py
ValueError: A LinearRing must have at least 3 coordinate tuples
Full environment definition
Operating system
MacOS Mojave 10.14.6
Cartopy version
Sources from the code repository February, 23rd 2020
conda list
# Name Version Build Channel
alabaster 0.7.12 py_0 conda-forge
appnope 0.1.0 py37_1000 conda-forge
astroid 2.3.3 py37_1 conda-forge
attrs 19.3.0 py_0 conda-forge
babel 2.8.0 py_0 conda-forge
backcall 0.1.0 py_0 conda-forge
bleach 3.1.1 py_0 conda-forge
ca-certificates 2019.11.28 hecc5488_0 conda-forge
cartopy 0.17.0 py37h6f81845_1010 conda-forge
certifi 2019.11.28 py37_0 conda-forge
cffi 1.13.2 py37h33e799b_0 conda-forge
chardet 3.0.4 py37_1003 conda-forge
cloudpickle 1.3.0 py_0 conda-forge
cryptography 2.8 py37hafa8578_1 conda-forge
cycler 0.10.0 py_2 conda-forge
dbus 1.13.6 h2f22bb5_0 conda-forge
decorator 4.4.1 py_0 conda-forge
defusedxml 0.6.0 py_0 conda-forge
docutils 0.16 py37_0 conda-forge
entrypoints 0.3 py37_1000 conda-forge
expat 2.2.9 h4a8c4bd_2 conda-forge
filelock 3.0.10 py_0 conda-forge
freetype 2.10.0 h24853df_1 conda-forge
geos 3.8.0 h4a8c4bd_0 conda-forge
gettext 0.19.8.1 h46ab8bc_1002 conda-forge
glib 2.58.3 py37h577aef8_1002 conda-forge
icu 64.2 h6de7cb9_1 conda-forge
idna 2.9 py_1 conda-forge
imagesize 1.2.0 py_0 conda-forge
importlib_metadata 1.5.0 py37_0 conda-forge
ipykernel 5.1.4 py37h5ca1d4c_0 conda-forge
ipython 7.12.0 py37h5ca1d4c_0 conda-forge
ipython_genutils 0.2.0 py_1 conda-forge
isort 4.3.21 py37_0 conda-forge
jedi 0.16.0 py37_0 conda-forge
jinja2 2.11.1 py_0 conda-forge
jpeg 9c h1de35cc_1001 conda-forge
jsonschema 3.2.0 py37_0 conda-forge
jupyter_client 5.3.4 py37_1 conda-forge
jupyter_core 4.6.3 py37_0 conda-forge
keyring 21.1.0 py37_0 conda-forge
kiwisolver 1.1.0 py37ha1b3eb9_0 conda-forge
lazy-object-proxy 1.4.3 py37h0b31af3_1 conda-forge
libblas 3.8.0 15_openblas conda-forge
libcblas 3.8.0 15_openblas conda-forge
libcxx 9.0.1 1 conda-forge
libffi 3.2.1 h6de7cb9_1006 conda-forge
libgfortran 4.0.0 2 conda-forge
libiconv 1.15 h01d97ff_1005 conda-forge
liblapack 3.8.0 15_openblas conda-forge
libopenblas 0.3.8 h3d69b6c_0 conda-forge
libpng 1.6.37 h2573ce8_0 conda-forge
libsodium 1.0.17 h01d97ff_0 conda-forge
libtiff 4.1.0 ha78913b_3 conda-forge
llvm-openmp 9.0.1 h28b9765_2 conda-forge
lz4-c 1.8.3 h6de7cb9_1001 conda-forge
markupsafe 1.1.1 py37h0b31af3_0 conda-forge
matplotlib-base 3.1.3 py37h11da6c2_0 conda-forge
mccabe 0.6.1 py_1 conda-forge
mistune 0.8.4 py37h0b31af3_1000 conda-forge
more-itertools 8.2.0 py_0 conda-forge
nbconvert 5.6.1 py37_0 conda-forge
nbformat 5.0.4 py_0 conda-forge
ncurses 6.1 h0a44026_1002 conda-forge
numpy 1.18.1 py37hde6bac1_0 conda-forge
numpydoc 0.9.2 py_0 conda-forge
olefile 0.46 py_0 conda-forge
openssl 1.1.1d h0b31af3_0 conda-forge
owslib 0.19.1 py_0 conda-forge
packaging 20.1 py_0 conda-forge
pandoc 2.9.2 0 conda-forge
pandocfilters 1.4.2 py_1 conda-forge
parso 0.6.1 py_0 conda-forge
pcre 8.44 h4a8c4bd_0 conda-forge
pexpect 4.8.0 py37_0 conda-forge
pickleshare 0.7.5 py37_1000 conda-forge
pillow 7.0.0 py37h918e99a_0 conda-forge
pip 20.0.2 py_2 conda-forge
pluggy 0.13.0 py37_0 conda-forge
proj 6.3.0 h773a61f_0 conda-forge
prompt_toolkit 3.0.3 py_0 conda-forge
psutil 5.7.0 py37h0b31af3_0 conda-forge
ptyprocess 0.6.0 py_1001 conda-forge
py 1.8.1 py_0 conda-forge
pycodestyle 2.5.0 py_0 conda-forge
pycparser 2.19 py_2 conda-forge
pyepsg 0.4.0 py_0 conda-forge
pyflakes 2.1.1 py_0 conda-forge
pygments 2.5.2 py_0 conda-forge
pykdtree 1.3.1 py37h3b54f70_1002 conda-forge
pylint 2.4.4 py37_0 conda-forge
pyopenssl 19.1.0 py_1 conda-forge
pyparsing 2.4.6 py_0 conda-forge
pyproj 2.5.0 py37hf8af742_0 conda-forge
pyqt 5.9.2 py37h2a560b1_4 conda-forge
pyrsistent 0.15.7 py37h0b31af3_0 conda-forge
pyshp 2.1.0 py_0 conda-forge
pysocks 1.7.1 py37_0 conda-forge
pytest 5.3.5 py37_1 conda-forge
python 3.7.6 h5c2c468_2 conda-forge
python-dateutil 2.8.1 py_0 conda-forge
python.app 1.2 py37h0b31af3_1201 conda-forge
pytz 2019.3 py_0 conda-forge
pyzmq 18.1.1 py37h4bf09a9_0 conda-forge
qt 5.9.7 h8cf7e54_3 conda-forge
qtawesome 0.7.0 py_0 conda-forge
qtconsole 4.6.0 py_0 conda-forge
qtpy 1.9.0 py_0 conda-forge
readline 8.0 hcfe32e1_0 conda-forge
requests 2.23.0 py37_0 conda-forge
rope 0.16.0 py_0 conda-forge
scipy 1.4.1 py37h82752d6_0 conda-forge
setuptools 45.2.0 py37_0 conda-forge
shapely 1.7.0 py37h999ffa5_0 conda-forge
sip 4.19.8 py37h0a44026_1000 conda-forge
six 1.14.0 py37_0 conda-forge
snowballstemmer 2.0.0 py_0 conda-forge
sphinx 2.4.3 py_0 conda-forge
sphinxcontrib-applehelp 1.0.1 py_0 conda-forge
sphinxcontrib-devhelp 1.0.1 py_0 conda-forge
sphinxcontrib-htmlhelp 1.0.3 py_0 conda-forge
sphinxcontrib-jsmath 1.0.1 py_0 conda-forge
sphinxcontrib-qthelp 1.0.2 py_0 conda-forge
sphinxcontrib-serializinghtml 1.1.3 py_0 conda-forge
spyder 3.3.5 py37_0 conda-forge
spyder-kernels 0.5.2 py37_0 conda-forge
sqlite 3.30.1 h93121df_0 conda-forge
testpath 0.4.4 py_0 conda-forge
tk 8.6.10 hbbe82c9_0 conda-forge
tornado 6.0.3 py37h0b31af3_4 conda-forge
traitlets 4.3.3 py37_0 conda-forge
typed-ast 1.4.1 py37h0b31af3_0 conda-forge
urllib3 1.25.7 py37_0 conda-forge
wcwidth 0.1.8 py_0 conda-forge
webencodings 0.5.1 py_1 conda-forge
wheel 0.34.2 py_1 conda-forge
wrapt 1.12.0 py37h0b31af3_0 conda-forge
wurlitzer 2.0.0 py37_0 conda-forge
xz 5.2.4 h1de35cc_1001 conda-forge
zeromq 4.3.2 h6de7cb9_2 conda-forge
zipp 3.0.0 py_0 conda-forge
zlib 1.2.11 h0b31af3_1006 conda-forge
zstd 1.4.4 he7fca8b_1 conda-forge
pip list