在使用Python、cartopy和matplotlib在我的shapefile数据的适当图中一起工作时,我面临着严重的困难。
这个问题来自于很难正确设置我的shapefile数据的转换和投影对象。
我在这里描述的示例相对于SIRGAS 2000投影中的SHP,其WKT格式是:
[“标准”,基准[“D_SIRGAS_2000”,球体“GRS_1980”,6378137,298.257222101],“格林威治”,0,单位“度”,0.017453292519943295]
从上面的WKT可以看出,我的坐标是度。地球仪不是WGS84,而是GRS_1980,它类似于(但不等于) WGS84。
这个crs还没有在cartopy中实现。因此,尝试使用函数作为cartopy.crs.EPSG(4674)不起作用,特别是因为这不是投影crs,而是地理crs。
按照绘图问题,我合理地假设我应该使用四个cartopy.crs选项中的一个来绘制数据:
transform_option_1 = cartopy.crs.PlateCarree() # works well
transform_option_2 = cartopy.crs.PlateCarree(globe=ccrs.Globe(ellipse='GRS80')) # works well
transform_option_3 = cartopy.crs.Geodetic(globe=ccrs.Globe(ellipse='GRS80')) # doesn't work
# using wkt:
WKT = """GEOGCS["SIRGAS 2000",DATUM["D_SIRGAS_2000",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]"""
transform_option_4 = ccrs.PlateCarree(WKT) # results in an error message (see message in annex)
然而,当我尝试四个转换选项来绘制我的数据时,我的transform_option_3和transform_option_4选项会出现一个错误。
前两个选项(transform_option_1,transform_option_2),一切都很好。另外,当我比较图中的前两个转换选项时,它们的结果是相同的,尽管它们应该会产生稍微不同的图(由于全局对象)。这是我的第一个问题:
问题1:为什么ccrs.PlateCarree()对象对我的数据产生相同的结果,尽管有不同的全局对象?
问题2:既然cartopy接受用于转换对象实例化的WKT字符串格式,为什么会出现错误?请参阅附在下面的错误消息(错误消息编号1)。
问题3:大地测量和板状投影在腕骨上有什么区别?我不知道什么时候该用。由于这两种投影的描述都以度表示坐标,所以它们的差异对我来说很奇怪。另外,当我尝试使用cartopy绘制我的超高压时,只有PlateCarree才能工作。其他的结果是黑色的地轴。
下面是一个代码片段,以更好地澄清我的问题3:
# importing libraries:
import geopandas as gpd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
# importing data:
SHP_path = 'Data_SHP.shp'
SHP = gpd.read_file(SHP_path)
# setting projection to PlateCarre:
projection = ccrs.PlateCarree() # projection.proj4_init
# setting SHP data transform
Transform2 = ccrs.Geodetic(globe=ccrs.Globe(ellipse='GRS80'))
# creating figure:
fig, ax = plt.subplots(1, subplot_kw={'projection':projection})
SHP.plot(ax=ax, transform=Transform2,
color='k', alpha=0.5)
# defining a small function to add grilines to the plot:
def custom_plot(geoaxes, projection):
gl = geoaxes.gridlines(crs=projection)
tick_axis_positions={'xlabels_top':False,
'ylabels_left':True,
'ylabels_right':False,
'xlabels_bottom':True}
gl.xlabels_top = tick_axis_positions['xlabels_top']
gl.ylabels_left = tick_axis_positions['ylabels_left']
gl.ylabels_right= tick_axis_positions['ylabels_right']
gl.xlabels_bottom = tick_axis_positions['xlabels_bottom']
return geoaxes
# adding gridlines to the geoaxes:
ax = custom_plot(ax, projection)
fig.show()
# end of code
问题4:为什么我不能用我的crs ( WKT格式)实例化一个cartopy投影对象?当我尝试这样做时,会出现一个错误消息(见附件中的错误消息2)。
Projection = ccrs.Projection(proj4_params=WKT, globe=ccrs.Globe(ellipse='GRS80'))
参考文献:
1) 关于如何从WKT或proj4坐标系投影格式创建proj4变换对象的讨论
附件:
错误信息1)
TypeError: unsupported operand type(s) for -: 'str' and 'float'
Traceback (most recent call last):
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\backends\backend_qt5.py", line 519, in _draw_idle
self.draw()
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\backends\backend_agg.py", line 402, in draw
self.figure.draw(self.renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\figure.py", line 1649, in draw
renderer, self, artists, self.suppressComposite)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\mpl\geoaxes.py", line 385, in draw
inframe=inframe)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\axes\_base.py", line 2628, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 262, in draw
transform, transOffset, offsets, paths = self._prepare_points()
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 240, in _prepare_points
for path in paths]
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 240, in <listcomp>
for path in paths]
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\transforms.py", line 2451, in transform_path_non_affine
return self._a.transform_path_non_affine(path)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\mpl\geoaxes.py", line 173, in transform_path_non_affine
src_path.vertices, self.source_projection)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\crs.py", line 746, in quick_vertices_transform
bboxes, proj_offset = self._bbox_and_offset(src_crs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\crs.py", line 709, in _bbox_and_offset
lon_0_offset = other_lon_0 - self_lon_0
TypeError: unsupported operand type(s) for -: 'str' and 'float'
Traceback (most recent call last):
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\backends\backend_qt5.py", line 519, in _draw_idle
self.draw()
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\backends\backend_agg.py", line 402, in draw
self.figure.draw(self.renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\figure.py", line 1649, in draw
renderer, self, artists, self.suppressComposite)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\mpl\geoaxes.py", line 385, in draw
inframe=inframe)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\axes\_base.py", line 2628, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\image.py", line 138, in _draw_list_compositing_images
a.draw(renderer)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\artist.py", line 50, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 262, in draw
transform, transOffset, offsets, paths = self._prepare_points()
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 240, in _prepare_points
for path in paths]
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\collections.py", line 240, in <listcomp>
for path in paths]
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\matplotlib\transforms.py", line 2451, in transform_path_non_affine
return self._a.transform_path_non_affine(path)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\mpl\geoaxes.py", line 173, in transform_path_non_affine
src_path.vertices, self.source_projection)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\crs.py", line 746, in quick_vertices_transform
bboxes, proj_offset = self._bbox_and_offset(src_crs)
File "C:\Users\lealp\AppData\Local\conda\conda\envs\Python_3.7\lib\site-packages\cartopy\crs.py", line 709, in _bbox_and_offset
lon_0_offset = other_lon_0 - self_lon_0
TypeError: unsupported operand type(s) for -: 'str' and 'float'
错误信息2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-165-9916b2ddcc67> in <module>
----> 1 ccrs.Projection(proj4_params=Transform_from_wkt, globe=ccrs.Globe(ellipse='GRS80'))
TypeError: Can't instantiate abstract class Projection with abstract methods boundary, threshold, x_limits, y_limits
发布于 2019-05-10 23:52:52
PlateCarree
使用lat/lons“投影”坐标来伪造。它实际上是等距圆柱,有一个特殊的默认地球仪,允许lat/lons工作。请参阅这只虫子中的更多内容。正因为如此,我认为将自定义GRS80地球仪传递给PlateCarree
并不是真正适合您的。那个窃听器概述了它破坏了一切。PlateCarree
的工作方式是将lat/lon作为平面上的坐标,因此lat/lon点之间的直线是平面上的直线。这是一个严重的简化,但它使许多事情,如轮廓。Geodetic
将lat/lons正确地视为球体上的坐标,因此连接lat/lons的直线是很棒的圆圈。这是正确的方法,但它使数学变得更复杂,不适用于一些绘图选项。请参阅这个例子以查看其变化情况。我很好奇,您遇到了哪些问题,将自定义椭球传递给Geodetic
。我对这个代码和Cartopy 0.17没有问题:
import cartopy.crs as ccrs
globe = ccrs.Globe(ellipse='GRS80')
crs = ccrs.Geodetic(globe=globe)
https://stackoverflow.com/questions/56045406
复制相似问题