cartopy icon indicating copy to clipboard operation
cartopy copied to clipboard

ValueError: 'vertices' must be 2D with shape (N, 2), but your input has shape (0,)

Open FlorianSuzat opened this issue 1 year ago • 9 comments

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

FlorianSuzat avatar Dec 03 '24 13:12 FlorianSuzat

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.

rcomer avatar Dec 03 '24 16:12 rcomer

The commit you referenced was not included in v0.24.

rcomer avatar Dec 03 '24 17:12 rcomer

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

FlorianSuzat avatar Dec 06 '24 14:12 FlorianSuzat

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 avatar Jul 16 '25 20:07 mhearne-usgs

@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.

greglucas avatar Jul 31 '25 03:07 greglucas

I could reproduce this error from a plt.tight_layout() call in cartopy v0.25

ameraner avatar Sep 19 '25 09:09 ameraner

@ameraner are you able to make a minimal reproducing example that demonstrates the problem? http://www.sscce.org/

rcomer avatar Sep 19 '25 10:09 rcomer

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.

rcomer avatar Sep 19 '25 10:09 rcomer

Sorry, I don't have the time right now - however I just tried to downgrade to v0.23 and indeed it solved the problem..

ameraner avatar Sep 19 '25 12:09 ameraner