首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在图解绘图中正确设置地轴的投影和变换

如何在图解绘图中正确设置地轴的投影和变换
EN

Stack Overflow用户
提问于 2019-05-08 16:42:44
回答 1查看 3.4K关注 0票数 1

在使用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选项中的一个来绘制数据:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
# 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)。

代码语言:javascript
运行
复制
Projection = ccrs.Projection(proj4_params=WKT, globe=ccrs.Globe(ellipse='GRS80'))

参考文献:

1) 关于如何从WKT或proj4坐标系投影格式创建proj4变换对象的讨论

2) 将proj4映射到cartopy CRS

3) 在Cartopy绘制一条直线,罗宾逊投影

4) 用cartopy绘制SHP的实例

5) cartopy变换与投影理论

附件:

错误信息1)

代码语言:javascript
运行
复制
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)

代码语言:javascript
运行
复制
---------------------------------------------------------------------------
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
EN

回答 1

Stack Overflow用户

发布于 2019-05-10 23:52:52

  1. PlateCarree使用lat/lons“投影”坐标来伪造。它实际上是等距圆柱,有一个特殊的默认地球仪,允许lat/lons工作。请参阅这只虫子中的更多内容。正因为如此,我认为将自定义GRS80地球仪传递给PlateCarree并不是真正适合您的。那个窃听器概述了它破坏了一切。
  2. 我不知道CartoPy实际上在任何地方都接受WKT。从Proj.4字符串或WKT创建一个投影,我认为这是一个公开发行
  3. PlateCarree的工作方式是将lat/lon作为平面上的坐标,因此lat/lon点之间的直线是平面上的直线。这是一个严重的简化,但它使许多事情,如轮廓。Geodetic将lat/lons正确地视为球体上的坐标,因此连接lat/lons的直线是很棒的圆圈。这是正确的方法,但它使数学变得更复杂,不适用于一些绘图选项。请参阅这个例子以查看其变化情况。
  4. 见上文(2)

我很好奇,您遇到了哪些问题,将自定义椭球传递给Geodetic。我对这个代码和Cartopy 0.17没有问题:

代码语言:javascript
运行
复制
import cartopy.crs as ccrs
globe = ccrs.Globe(ellipse='GRS80')
crs = ccrs.Geodetic(globe=globe)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56045406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档