使用cartopy在其他项目中绘制投影数据

时间:2017-02-14 22:59:37

标签: python matplotlib plot cartopy

这个问题涉及绘制一些使用Lambert Conformal(LCC)CRS的数据。虽然这些问题特别适用于在多个投影中绘制LCC数据,但它也适用于一般的折叠使用,因为我希望更好地理解使用折叠图进行绘图的逻辑/过程。

以下是我正在尝试做的一些代码示例。第一个例子是简单地绘制一些LCC数据。我使用的数据可在链接here中找到。

import cartopy.crs as ccrs
import cartopy.feature as cf
import matplotlib.pyplot as plt
import numpy as np

proj = ccrs.LambertConformal(central_latitude = 25, 
                             central_longitude = 265, 
                             standard_parallels = (25, 25))

# Data and coordinates (from download link above)
with np.load('nam_218_20120414_1200_006.npz') as nam:
   dat = nam['dpc']
   lat = nam['lat']
   lon = nam['lon']

ax = plt.axes(projection = proj)
ax.pcolormesh(lon, lat, dat, transform = ccrs.PlateCarree())
ax.add_feature(cf.NaturalEarthFeature(
               category='cultural',
               name='admin_1_states_provinces_lines',
               scale='50m',
               facecolor='none'))
ax.coastlines('50m')
ax.add_feature(cf.BORDERS)
plt.show()

制作的情节可以在这里看到:

LCC地图上的美国露点

使用cartopy时我的第一个困惑是为什么在绘图时我总是要转换为PlateCarree?我最初的想法是transform调用的pcolormesh关键字需要LCC投影信息,而不是PlateCarree

接下来,如果我想在另一个投影中绘制我的LCC数据,例如正交,我会像下面这样做吗?

# First, transform from LCC to Orthographic
transform = proj.transform_points(ccrs.Orthographic(265,25), lon, lat)
x = transform[..., 0]
y = transform[..., 1]

ax = plt.axes(projection = ccrs.Orthographic(265,25))
ax.pcolormesh(x, y, dat, transform = ccrs.PlateCarree())
ax.add_feature(cf.NaturalEarthFeature(
               category='cultural',
               name='admin_1_states_provinces_lines',
               scale='50m',
               facecolor='none'))
ax.coastlines('50m')
ax.add_feature(cf.BORDERS)
ax.set_global()

制作的情节可以在这里看到:

美国露点地图上的露点

我认为正交图看起来不错,但我想确定我理解正确重新投影的过程。

总之,我想知道以下事项:

  1. 在绘图时,您始终需要transformPlateCarree吗?为什么或为什么不呢?
  2. 重新投影只是需要调用transform_points方法,还是涉及其他步骤?
  3. 更新1

    根据@swatchai的答案,似乎我的问题2的答案是transform_points不是必需的。可以在许多matplotlib绘图方法中使用transform关键字参数。这就是我原来的想法。但是,跳过transform_points对我没用。见下面的例子:

    ax = plt.axes(projection = ccrs.Orthographic(265,25))
    ax.pcolormesh(lon, lat, dat, transform = proj)
    ax.add_feature(cf.NaturalEarthFeature(
                   category='cultural',
                   name='admin_1_states_provinces_lines',
                   scale='50m',
                   facecolor='none'))
    ax.coastlines('50m')
    ax.add_feature(cf.BORDERS)
    ax.set_global()
    

    产生这个情节:

    没有transform_points的正交图步骤

    问题似乎是lat和lon输入没有转换为网格坐标,所以它们只能绘制在图的极小区域内。那么,为了扩展问题2,如果你应该跳过transform_points根据我上面的例子,是否存在卡片绘图方法中的错误?或者我还缺少一步?

2 个答案:

答案 0 :(得分:4)

在Cartopy中,ccrs.PlateCarree()是最基本的地图投影,有时称为非投影投影,即以度为单位的地理位置(纬度,长度) - >变成网格值y = lat;在PlateCarree地图上x = long。

此代码段:

import cartopy.crs as ccrs
axm = plt.axes( projection = ccrs.xxxx() ) 

创建一个轴axm,用于在xxxx投影中绘制地图。在axm上绘制数据时,默认坐标是该投影的网格(x,y)(通常以米为单位)。这就是为什么你需要transform=ccrs.PlateCarree()声明你的输入(x,y)确实在(长,纬度)度,或者换句话说,在(x,y)PlateCarree网格坐标中。

如果您的目标投影是正交,而数据是LambertConformal,

ax = plt.axes(projection = ccrs.Orthographic(265,25))
lccproj = ccrs.LambertConformal(central_latitude = 25, 
                         central_longitude = 265, 
                         standard_parallels = (25, 25))

您可以使用

绘制数据
ax.pcolormesh(x, y, dat, transform = lccproj)

执行绘图时,根本不需要使用transform_points()。但是在某些情况下想要访问转换后的坐标时非常有用。

答案 1 :(得分:3)

需要在地理和投影(或网格)坐标之间进行重要区分。可以在here找到更详细的描述。重要的是,有助于回答问题1的是,纬度和经度是地理坐标,而以米为单位的点是投影坐标。

示例数据来自的数值天气模型在其计算中使用Lambert Conformal投影(更多here)。但是,输出的坐标是纬度和经度。如果您对空间数据缺乏经验,那么当它们实际上是 geogrphic 坐标时,您最终可能会认为lat / lon对是LCC 投影坐标;在模型集成期间使用LCC内容。

要回答问题1,不,您不必总是使用PlateCarree作为源CRS。但是,您始终使用PlateCarree作为纬度和经度数据(这是此处的情况)。这样,cartopy将正确地将您的lat / lon值转换为投影坐标(以米为单位),并且能够在绘图期间轻松地将transform数据转换为其他投影。这个问题最终是更新1中看似空白的情节的原因。通过说源数据具有transform中的LCC投影坐标,折叠采用纬度/经度输入并将它们解释为具有米的单位。确实绘制了数据,但范围太小,以至于在不将绘图范围更改为与数据相同的情况下无法看到它们。

关于问题2,不,使用transform_points不是必需的。以这样的方式设置了纸箱,使得在具有最小中间步骤的多个投影中容易绘图。正如@swatchai所提到的,有时你可能想要使用实际的投影坐标,并且使用transform_points方法可以让你这样做。当transform_points用于在原始帖子中生成第二个绘图时,如果PlateCarree中的transform已正确处理输入坐标,则基本上是手动完成自动执行的操作。

最后,@ ajdawson在绘图时如何使用projectiontransform做了一个重要的澄清。一旦了解了源坐标的含义,此信息也很有用。评论引用如下:

  

一般情况下,projection会告诉图解绘制的地图应该是什么样的,而transform会告诉图表您的数据所代表的坐标系。您可以将projection设置为任何投影你比如,transform需要匹配您的数据使用的任何坐标系。