间隔数据的Cartopy绘图问题

时间:2018-04-17 08:53:23

标签: python cartopy

我试图在离散间隔的Cartopy网格上绘制数据。数据范围从0到1,其间的间距为0.05。在某些(看似随机的)场合,Python会抛出错误说:

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

此后会弹出另一个OSError(问题末尾会给出回溯)。对于以下简短示例,该问题在大约70%的时间内重现:

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)

随机性使我觉得错误只发生在某些配置上(例如,1与两侧的-1并置)。

此错误的一个不寻常的方面是,当不包括日期行时(例如,仅绘制从0到170E),它变得不那么频繁。即使是短距离(例如,170E到170W)也包含日期线,错误会再次发生,频率约为70%。

我的问题是:示例中出了什么问题?或者这可能是Cartopy中的内部错误?

以下是初始错误消息后的完整回溯报告:

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版本为0.16。

谢谢!

1 个答案:

答案 0 :(得分:0)

您的轮廓数据必须对处理有效。这是工作代码。

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()

结果图片: enter image description here