简体   繁体   中英

Cartopy plotting issue for interval data

I am trying to plot data on a Cartopy grid with discrete intervals. The data ranges from 0 to 1 with a spacing of 0.05 in between. On some (seemingly random) occasions Python throws in an error saying:

IllegalArgumentException: Invalid number of points in LinearRing found 3 - must be 0 or >= 4

After this another OSError pops up (traceback is given at the end of the question). The issue is reproduced in about 70% of the time for the short example below:

V=np.arange(-1,1.05,0.05)
array_fill = np.random.random((71,361))*20//1/20
plt.figure()
ax = plt.axes(projection = ccrs.PlateCarree())
proj = ccrs.PlateCarree()
lon = np.arange(0,361)
lat = np.arange(20,91)
ax.coastlines(resolution='110m')
ax.gridlines()
ax.contourf(lon,lat,array_fill, V, cmap = cm.jet)

The randomness makes it seem to me that the error only occurs for some configurations (say, a 1 being collocated with a -1 on both sides).

One unusual aspect to this error is that it becomes less frequent when the dateline is not included (say, only plotting from 0 to 170E). When the dateline is included even for a short range (say, 170E to 170W), the error occurs with a frequency of about 70% again.

My question is: what is going wrong in the example? Or could this be an internal bug in Cartopy?

Here is the full traceback report after the initial error message:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\backends\backend_qt5.py", line 519, in _draw_idle
self.draw()
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\backends\backend_agg.py", line 433, in draw
self.figure.draw(self.renderer)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\figure.py", line 1475, in draw
renderer, self, artists, self.suppressComposite)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\cartopy\mpl\geoaxes.py", line 385, in draw
inframe=inframe)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\axes\_base.py", line 2607, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\collections.py", line 911, in draw
Collection.draw(self, renderer)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\collections.py", line 266, in draw
transform, transOffset, offsets, paths = self._prepare_points()
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\collections.py", line 244, in _prepare_points
for path in paths]
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\collections.py", line 244, in <listcomp>
for path in paths]
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\matplotlib\transforms.py", line 2499, in transform_path_non_affine
return self._a.transform_path_non_affine(path)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\cartopy\mpl\geoaxes.py", line 193, in transform_path_non_affine
geom, self.source_projection)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\cartopy\crs.py", line 181, in project_geometry
return getattr(self, method_name)(geometry, src_crs)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\cartopy\crs.py", line 336, in _project_polygon
return self._rings_to_multi_polygon(rings, is_ccw)
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\cartopy\crs.py", line 526, in _rings_to_multi_polygon
if ring.is_ccw != is_ccw:
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\geometry\polygon.py", line 86, in is_ccw
return bool(self.impl['is_ccw'](self))
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\algorithms\cga.py", line 14, in is_ccw_op
return signed_area(ring) >= 0.0
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\algorithms\cga.py", line 6, in signed_area
xs, ys = ring.coords.xy
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\geometry\base.py", line 322, in _get_coords
if self.is_empty:
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\geometry\base.py", line 643, in is_empty
return (self._geom is None) or bool(self.impl['is_empty'](self))
  File "C:\Program Files (x86)\Anaconda\lib\site-packages\shapely\predicates.py", line 25, in __call__
return self.fn(this._geom)
OSError: exception: access violation reading 0x0000000000000000

Cartopy version is 0.16.

Thanks!

Your data for contouring must be valid for the processing. Here is the working code.

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import matplotlib 
import matplotlib.cm as cm

V = np.arange(-1, 1.05, 0.05)

# The data must be valid for contouring
#  with (*20//1/20), the data is not fine-grained enough
array_fill = np.random.random((71, 361))*2000//1/2000
plt.figure(figsize=[12,8])
ax = plt.axes(projection = ccrs.PlateCarree())
# proj = ccrs.PlateCarree()
lon = np.arange(0, 361)
lat = np.arange(20, 91)
ax.coastlines(resolution='110m', color='blue', linewidth=2)
ax.gridlines()

# (lon, lat) can't be used directly,
#   meshgrid must be created from them
xs, ys  = np.meshgrid(lon, lat)
ax.contourf(xs, ys, array_fill, V, cmap = cm.jet)

plt.show()

The resulting image: 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM