3

When trying to plot a 2D array in cartopy projected axes using contourf, I am receiving a TopologicalError. This is the code:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np
from shapely.geos import TopologicalError

data = np.array(
       [[ 8, 10,  2, 5, 3,  6,  5,  3,  0,  0,  0,  0,  0,  0,  0],
        [ 7,  5,  3, 6, 5,  4,  2,  1,  1,  0,  0,  0,  0,  0,  0],
        [ 8, 10,  2, 7, 1,  2,  1,  0,  0,  1,  0,  0,  0,  0,  0],
        [14,  8, 12, 9, 3,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0],
        [15,  8, 10, 5, 2,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 7,  7,  9, 5, 2,  2,  1,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 4,  5,  1, 2, 0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 2,  4,  1, 3, 1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 2,  0,  0, 1, 2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 0,  0,  1, 1, 1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
        ])

x = np.array([-9.05365, -9.05266, -9.05167, -9.05068, -9.04969,
              -9.0487, -9.04771, -9.04672, -9.04573, -9.04474,
              -9.04375, -9.04276, -9.04177, -9.04078, -9.03979])

y = np.array([53.2024, 53.203, 53.2036, 53.2042, 53.2048,
              53.2054, 53.206, 53.2065, 53.2071, 53.2077])

data = np.ma.masked_where(data==0, data)

ax = plt.axes(projection=ccrs.Mercator(central_longitude=-9))

try:
    ax.contourf(x, y, data, transform=ccrs.PlateCarree())
except TopologicalError as exc:
    pass # Do something to get the conflicting location (x, y) 

When running this code, I am getting the TopologyException message below, followed by a rather long traceback (see below). The TopologyException is:

TopologyException: side location conflict at -9.0506799999999998 53.206000000000003

Now, under the except block, I would like to fix the array in the location indicated by the TopologyException (-9.0506799999999998 53.206000000000003), and try to plot it again. I would use a while loop to fix the array as many times as needed, retrieving the conflicting location and fixing the array at that location. I have to repeat this procedure for many other arrays like this.

Even though the message is displayed in the screen, I don't know how to get the location -9.0506799999999998 53.206000000000003 from the script, since I can't find it in exc. I would be very grateful if somebody could explain how to get those numbers as new variables lon and lat.

This error can be avoided if not using a masked array, but I am masking the 0's because I don't want to plot them.

Below is the traceback. Many thanks.

TopologyException: side location conflict at -9.0506799999999998 53.206000000000003
TopologyException: side location conflict at -9.0506799999999998 53.206000000000003
Error in callback <function install_repl_displayhook.<locals>.post_execute at 0x00000204E9F74280> (for post_execute):
Traceback (most recent call last):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\predicates.py", line 15, in __call__
    return self.fn(this._geom, other._geom, *args)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\geos.py", line 584, in errcheck_predicate
    raise PredicateError("Failed to evaluate %s" % repr(func))

PredicateError: Failed to evaluate <_FuncPtr object at 0x00000204EB13ED40>


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\pyplot.py", line 139, in post_execute
    draw_all()

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\_pylab_helpers.py", line 137, in draw_all
    manager.canvas.draw_idle()

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\backend_bases.py", line 2055, in draw_idle
    self.draw(*args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\backends\backend_agg.py", line 406, in draw
    self.figure.draw(self.renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 74, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\figure.py", line 2790, in draw
    mimage._draw_list_compositing_images(

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\geoaxes.py", line 558, in draw
    return matplotlib.axes.Axes.draw(self, renderer=renderer, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\_api\deprecation.py", line 431, in wrapper
    return func(*inner_args, **inner_kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\axes\_base.py", line 2921, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 1012, in draw
    super().draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 352, in draw
    transform, transOffset, offsets, paths = self._prepare_points()

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 329, in _prepare_points
    paths = [transform.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 329, in <listcomp>
    paths = [transform.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\transforms.py", line 2396, in transform_path_non_affine
    return self._a.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\geoaxes.py", line 186, in transform_path_non_affine
    geoms = cpatch.path_to_geos(src_path,

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\patch.py", line 178, in path_to_geos
    collection[-1][0].contains(geom.exterior)):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\geometry\base.py", line 747, in contains
    return bool(self.impl['contains'](self, other))

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\predicates.py", line 18, in __call__
    self._check_topology(err, this, other)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\topology.py", line 35, in _check_topology
    raise TopologicalError(

TopologicalError: The operation 'GEOSContains_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x000002048290D820>

TopologyException: side location conflict at -9.0506799999999998 53.206000000000003
Traceback (most recent call last):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\predicates.py", line 15, in __call__
    return self.fn(this._geom, other._geom, *args)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\geos.py", line 584, in errcheck_predicate
    raise PredicateError("Failed to evaluate %s" % repr(func))

PredicateError: Failed to evaluate <_FuncPtr object at 0x00000204EB13ED40>


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\IPython\core\formatters.py", line 341, in __call__
    return printer(obj)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\IPython\core\pylabtools.py", line 253, in <lambda>
    png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\IPython\core\pylabtools.py", line 137, in print_figure
    fig.canvas.print_figure(bytes_io, **kw)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\backend_bases.py", line 2230, in print_figure
    self.figure.draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 74, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\figure.py", line 2790, in draw
    mimage._draw_list_compositing_images(

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\geoaxes.py", line 558, in draw
    return matplotlib.axes.Axes.draw(self, renderer=renderer, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\_api\deprecation.py", line 431, in wrapper
    return func(*inner_args, **inner_kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\axes\_base.py", line 2921, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 1012, in draw
    super().draw(renderer)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 352, in draw
    transform, transOffset, offsets, paths = self._prepare_points()

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 329, in _prepare_points
    paths = [transform.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\collections.py", line 329, in <listcomp>
    paths = [transform.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\matplotlib\transforms.py", line 2396, in transform_path_non_affine
    return self._a.transform_path_non_affine(path)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\geoaxes.py", line 186, in transform_path_non_affine
    geoms = cpatch.path_to_geos(src_path,

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\cartopy\mpl\patch.py", line 178, in path_to_geos
    collection[-1][0].contains(geom.exterior)):

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\geometry\base.py", line 747, in contains
    return bool(self.impl['contains'](self, other))

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\predicates.py", line 18, in __call__
    self._check_topology(err, this, other)

  File "C:\Users\dpereiro\Miniconda3\envs\opendrift\lib\site-packages\shapely\topology.py", line 35, in _check_topology
    raise TopologicalError(

TopologicalError: The operation 'GEOSContains_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x00000204E87FDD90>

<Figure size 432x288 with 1 Axes>
DRod07
  • 33
  • 2

0 Answers0