6

这个问题是关于绘制一些我拥有的使用 Lambert Conformal (LCC) CRS 的数据。虽然这些问题特别涉及在多个投影中绘制 LCC 数据,但它也适用于一般的 cartopy 使用,因为我想更好地理解使用 cartopy 绘制的逻辑/过程。

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

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

产生的情节可以在这里看到:

正交地图上的美国露点

我认为正交地图看起来是正确的,但我想确保我正确理解了用 cartopy 重新投影的过程。

总之,我想知道以下几点:

  1. 绘图时总是必须这样做transform吗?PlateCarree为什么或者为什么不?
  2. 重新投影是否只需要调用该transform_points方法或是否涉及其他步骤?

更新 1

根据@swatchai的回答,我的问题 2 的答案似乎transform_points不是必需的。transform可以在许多 matplotlib 绘图方法中简单地使用关键字参数。这是我最初的想法。但是,跳过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 步骤的正交图

问题似乎是纬度和经度输入没有转换为网格坐标,因此它们仅被绘制在图的极小区域中。因此,为了扩展问题 2,如果您应该跳过transform_points,根据我上面的示例,cartopy 的绘图方法是否存在错误?还是我还缺少一步?

4

2 回答 2

6

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

示例数据来自的数值天气模型在其计算中使用了 Lambert Conformal 投影(更多信息请点击此处)。但是,得到输出的坐标是纬度和经度。如果您对空间数据缺乏经验,您最终可能会认为纬度/经度对是 LCC投影坐标,而实际上它们是地理坐标;在模型集成期间使用 LCC 的东西。

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

关于问题 2,不,使用transform_points不是必需的。cartopy 的设置方式是通过最少的中间步骤轻松绘制多个投影。正如@swatchai 提到的,有时您可能想要使用实际的投影坐标,并且使用该transform_points方法将允许您这样做。当transform_points用于在原始帖子中生成第二个图时,它本质上是手动执行如果输入坐标正确处理会自动完成的操作PlateCarreein transform

最后,@ajdawson 就如何使用projection以及transform何时绘制进行了重要说明。一旦您了解了源坐标的内容,此信息也很有用。评论引述如下:

一般来说,projection告诉 cartopy 绘制的地图应该是什么样子,并transform告诉 cartopy 您的数据在哪个坐标系中表示。您可以设置projection为您喜欢的任何投影,但transform需要匹配您的数据使用的任何坐标系。

于 2017-02-24T21:16:38.267 回答
5

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

此片段代码:

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

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

如果您的目标投影是正交投影,而数据是 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() 。但是当您想在某些情况下访问转换后的坐标时,它很有用。

于 2017-02-15T04:32:49.467 回答