ValueError: 'vertices' must be 2D with shape (N, 2), but your input has shape (0,)
Description
since version 0.24 (commit 8bb65fbd259a1cfbd6f90c9716daf413ef31e965), I encounter a problem with cartopy. Here is the traceback.
Traceback
Traceback (most recent call last):
File "/home/gmap/mrpa/suzat/tmp/toto.py", line 6, in <module>
fig.savefig('toto.png')
File "#PATH#/matplotlib/figure.py", line 3395, in savefig
self.canvas.print_figure(fname, **kwargs)
File "#PATH#/matplotlib/backend_bases.py", line 2204, in print_figure
result = print_method(
File "#PATH#/matplotlib/backend_bases.py", line 2054, in <lambda>
print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
File "#PATH#/matplotlib/backends/backend_agg.py", line 496, in print_png
self._print_pil(filename_or_obj, "png", pil_kwargs, metadata)
File "#PATH#/matplotlib/backends/backend_agg.py", line 444, in _print_pil
FigureCanvasAgg.draw(self)
File "#PATH#/matplotlib/backends/backend_agg.py", line 387, in draw
self.figure.draw(self.renderer)
File "#PATH#/matplotlib/artist.py", line 95, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "#PATH#/matplotlib/artist.py", line 72, in draw_wrapper
return draw(artist, renderer)
File "#PATH#/matplotlib/figure.py", line 3162, in draw
mimage._draw_list_compositing_images(
File "#PATH#/matplotlib/image.py", line 132, in _draw_list_compositing_images
a.draw(renderer)
File "#PATH#/matplotlib/artist.py", line 72, in draw_wrapper
return draw(artist, renderer)
File "#PATH#/cartopy/mpl/geoaxes.py", line 511, in draw
self._draw_preprocess()
File "#PATH#/cartopy/mpl/geoaxes.py", line 487, in _draw_preprocess
self.patch._adjust_location()
File "#PATH#/cartopy/mpl/geoaxes.py", line 240, in _adjust_location
cpatch._ensure_path_closed(
File "#PATH#/cartopy/mpl/patch.py", line 49, in _ensure_path_closed
return Path(vertices, codes)
File "#PATH#/matplotlib/path.py", line 130, in __init__
_api.check_shape((None, 2), vertices=vertices)
File "#PATH#/matplotlib/_api/__init__.py", line 161, in check_shape
raise ValueError(
ValueError: 'vertices' must be 2D with shape (N, 2), but your input has shape (0,)
Here some useful prints...
#PATH#/cartopy/mpl/geoaxes.py 237 viewLim Bbox(x0=-772850.0000000698, y0=-772850.0000000224, x1=787149.9999999468, y1=787149.9999999979)
#PATH#/cartopy/mpl/geoaxes.py 238 _original_path.clip_to_bbox Path(array([], shape=(0, 2), dtype=float64), None)
I'm not expert in matplolib/cartopy stuff, so not able to be sure of the real source of the problem, and how to fix it... Any help will be appreciated...
Operating system
linux
Cartopy version
0.24
pip list
pip list Package Version
asttokens 2.4.1 attrs 24.2.0 bcrypt 4.2.0 bronx 2.0.0 Cartopy 0.24.1 certifi 2024.8.30 cffi 1.17.1 cftime 1.6.4 charset-normalizer 3.4.0 contourpy 1.3.1 cryptography 43.0.3 ctypesForFortran 1.1.3 cycler 0.12.1 decorator 5.1.1 eccodes 1.7.1 epygram 1.5.2 exceptiongroup 1.2.2 executing 2.1.0 findlibs 0.0.5 fonttools 4.55.1 footprints 2.0.0 futures 3.0.5 h5py 3.12.1 idna 3.10 ipython 8.29.0 jedi 0.19.1 Jinja2 3.1.4 kiwisolver 1.4.7 MarkupSafe 3.0.1 matplotlib 3.9.3 matplotlib-inline 0.1.7 netCDF4 1.7.1.post2 numpy 2.1.3 packaging 24.2 panda 0.3.1 pandas 2.2.3 paramiko 3.5.0 parso 0.8.4 pexpect 4.9.0 pillow 11.0.0 pip 24.2 prompt_toolkit 3.0.48 ptyprocess 0.7.0 pure_eval 0.2.3 pycparser 2.22 Pygments 2.18.0 PyNaCl 1.5.0 pyparsing 3.2.0 pyproj 3.7.0 pyshp 2.3.1 python-dateutil 2.9.0.post0 pytz 2024.2 PyYAML 6.0.2 requests 2.32.3 setuptools 75.6.0 setuptools-scm 8.1.0 shapely 2.0.6 six 1.16.0 stack-data 0.6.3 tomli 2.2.1 traitlets 5.14.3 typing_extensions 4.12.2 tzdata 2024.2 urllib3 2.2.3 wcwidth 0.2.13
Hello @FlorianSuzat, please could you provide a code example that we can run to reproduce the problem? We cannot debug anything that we cannot reproduce.
The commit you referenced was not included in v0.24.
Hi, sorry for late answer. I have got this problem inside a graphical package called epygram that uses cartopy plot backend. I'm not currently able to reproduce the problem outside this. For the commit I mentionned, it is an error using git blame. I will try to reproduce it in a ideal test case then I send it here
Below is a short script that demonstrates this error. When I run this on my laptop (WSL with Ubuntu 20.04) with Cartopy 0.24.0 or higher, I get this output:
Failed to create a geoaxes with error 'vertices' must be 2D with shape (N, 2), but your input has shape (0,):
central longitude -24.000000006240025
maximum latitude 85.31250000018649
figure size (7.0, 6.427859137780603)
Succeeded in creating a geoaxes with:
central longitude 6.174999992552969
maximum latitude 85.76250000016849
figure size (7.0, 6.871316294394416)
When I downgrade to Cartopy 0.23.0, the error does not occur.
#!/usr/bin/env python
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def get_axes(clon, ymin, ymax, figsize):
try:
proj = ccrs.Mercator(
central_longitude=clon,
max_latitude=ymax,
min_latitude=ymin,
globe=None,
)
dimensions = (0, 0, 1, 1)
figure = plt.figure(figsize=figsize)
ax = figure.add_axes(dimensions, projection=proj)
print("Succeeded in creating a geoaxes with:")
except Exception as e:
print(f"Failed to create a geoaxes with error {e}:")
print(f"\t central longitude {clon}")
print(f"\t maximum latitude {ymax}")
print(f"\t figure size {figsize}")
if __name__ == "__main__":
# greenland event
clon, ymin, ymax = (-24.000000006240025, 80.233, 85.31250000018649)
figsize = (7.0, 6.427859137780603)
get_axes(clon, ymin, ymax, figsize)
# svalbard event
clon, ymin, ymax = (6.174999992552969, 82.167, 85.76250000016849)
figsize = (7.0, 6.871316294394416)
get_axes(clon, ymin, ymax, figsize)
@mhearne-usgs thank you for that simple reproducer! It does look like that fails on v0.24, but is passing on main. So that specific case will be fixed in the upcoming release. If there are other cases, it would be good to try this against main to see if things have actually been fixed or we just got a bit lucky.
I could reproduce this error from a plt.tight_layout() call in cartopy v0.25
@ameraner are you able to make a minimal reproducing example that demonstrates the problem? http://www.sscce.org/
Actually I think I found the culprit. _ensure_path_closed does not handle an empty path.
from cartopy.mpl.path import _ensure_path_closed
from matplotlib.path import Path
import numpy as np
empty_path = Path(np.zeros((0, 2)))
_ensure_path_closed(empty_path)
File "/<snip>/cartopy_2488.py", line 6, in <module>
_ensure_path_closed(empty_path)
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/<snip>/cartopy/lib/cartopy/mpl/path.py", line 51, in _ensure_path_closed
return Path(vertices, codes)
File "/<snip>site-packages/matplotlib/path.py", line 129, in __init__
_api.check_shape((None, 2), vertices=vertices)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/<snip>/site-packages/matplotlib/_api/__init__.py", line 172, in check_shape
raise ValueError(
...<2 lines>...
)
ValueError: 'vertices' must be 2D with shape (N, 2), but your input has shape (0,)
Though from the context of where this function gets called, I don't get why we would have empty paths - it seems to be about the GeoAxes boundary, etc.
Sorry, I don't have the time right now - however I just tried to downgrade to v0.23 and indeed it solved the problem..