很容易混淆投影和变换关键字参数的实际含义。在这里,我们将使用一些简单的例子来说明每种方法的效果。
核心概念是子图(或轴 zxes)的投影独立于定义数据的坐标系。“投影”参数用于创建绘图并确定结果绘图的投影(即绘图的外观)。plotting函数的transform参数告诉Cartopy数据在哪个坐标系中定义。
首先,我们将创建一些在常规纬度/经度网格上定义的虚拟数据:
import numpy as np
lon = np.linspace(-80, 80, 25)
lat = np.linspace(30, 70, 25)
lon2d, lat2d = np.meshgrid(lon, lat)
data = np.cos(np.deg2rad(lat2d) * 4) + np.sin(np.deg2rad(lon2d) * 4)
让我们尝试在PlateCarree投影中绘制一个图,而不指定transform参数。由于数据恰好是在我们正在绘制的同一坐标系中定义的,因此这实际上是正确的:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
# The projection keyword determines how the plot will look
plt.figure(figsize=(6, 3))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()
ax.contourf(lon, lat, data) # didn't use transform, but looks ok...
plt.show()
下面我们加入 transform关键字:
# The data are defined in lat/lon coordinate system, so PlateCarree()
# is the appropriate choice:
data_crs = ccrs.PlateCarree()
# The projection keyword determines how the plot will look
plt.figure(figsize=(6, 3))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()
ax.contourf(lon, lat, data, transform=data_crs)
plt.show()
看到画的图没有改变吗?这是因为未提供transform参数时的默认假设是坐标系与投影匹配,到目前为止一直如此。
现在,我们将再次尝试此操作,但对绘图使用不同的投影。我们将绘制到旋转的极点投影上,我们将省略transform参数以查看发生了什么:
# Now we plot a rotated pole projection
projection = ccrs.RotatedPole(pole_longitude=-177.5, pole_latitude=37.5)
plt.figure(figsize=(6, 3))
ax = plt.axes(projection=projection)
ax.set_global()
ax.coastlines()
ax.contourf(lon, lat, data) # didn't use transform, uh oh!
plt.show()
结果图不正确!我们没有告诉Cartopy我们的数据是在什么坐标系中定义的,所以它假设它与我们正在绘制的投影相同,并且数据绘制在错误的位置。
我们可以通过提供transform参数来解决此问题,该参数与以前相同,因为数据的坐标系没有更改:
# A rotated pole projection again...
projection = ccrs.RotatedPole(pole_longitude=-177.5, pole_latitude=37.5)
data_crs = ccrs.PlateCarree()
plt.figure(figsize=(6, 3))
ax = plt.axes(projection=projection)
ax.set_global()
ax.coastlines()
# ...but now using the transform argument
ax.contourf(lon, lat, data, transform=data_crs)
plt.show()
最安全的做法是始终提供transform关键字,而不考虑使用的投影,并避免让Cartopy对数据的坐标系进行假设。这样做允许您为绘图选择任何地图投影,并允许Cartopy在数据应位于的位置绘制数据:
# We can choose any projection we like...
projection = ccrs.InterruptedGoodeHomolosine()
plt.figure(figsize=(6, 7))
ax1 = plt.subplot(211, projection=projection)
ax1.set_global()
ax1.coastlines()
ax2 = plt.subplot(212, projection=ccrs.NorthPolarStereo())
ax2.set_extent([-180, 180, 20, 90], crs=ccrs.PlateCarree())
ax2.coastlines()
# ...as long as we provide the correct transform, the plot will be correct
ax1.contourf(lon, lat, data, transform=data_crs)
ax2.contourf(lon, lat, data, transform=data_crs)
plt.show()