使用 cartopy 在其他投影仪中绘制投影数据 [英] Plotting projected data in other projectons using cartopy
问题描述
这个问题与绘制一些我使用兰伯特保形(LCC)CRS的数据有关.虽然这些问题特别涉及在多个投影中绘制LCC数据,但它也适用于一般使用Cartopy的情况,因为我想更好地了解使用Cartopy进行绘制的逻辑/过程.
以下是我正在尝试做的一些代码示例.第一个示例只是绘制一些 LCC 数据.在链接的答案,似乎我对问题2的答案是不需要transform_points
.可以在许多 matplotlib 绘图方法中简单地使用 transform
关键字参数.这就是我最初的想法.但是,跳过 transform_points
对我来说不起作用.请参见下面的示例:
ax = plt.axes(投影= ccrs.Orthographic(265,25))ax.pcolormesh(lon,lat,dat,transform = proj)ax.add_feature(cf.NaturalEarthFeature(category ='文化',name ='admin_1_states_provinces_lines',规模='50m',facecolor='无'))ax.coastlines('50m')ax.add_feature(cf.BORDERS)ax.set_global()
产生以下情节的地方:
没有transform_points步骤的正交图
问题似乎是 lat 和 lon 输入没有转换为网格坐标,因此它们只绘制在图的极小区域中.因此,为了扩展问题2,如果您应该跳过 transform_points
,那么根据我上面的示例,cartopy的绘制方法是否存在错误?还是我还缺一步?
需要在地理坐标和投影(或网格)坐标之间进行重要区分.有关这些内容的详细说明,请参见此处).但是,输出的坐标是纬度和经度.如果您对空间数据缺乏经验,您可能会以为纬度/经度对实际上是
要回答问题 1,不,您不必总是使用 PlateCarree
作为源 CRS.但是,您确实总是对纬度和经度数据使用 PlateCarree
(在这种情况下).这样,cartopy可以将纬度/经度值正确转换为投影的坐标(以米为单位),并能够在绘图过程中轻松地将代码转换为其他投影.这个问题最终是Update 1中看似空白图的原因.通过说源数据在 transform
中具有LCC投影坐标,cartopy接受了经/纬度输入并将其解释为具有米的单位.数据确实被绘制出来了,但是范围太小了,如果不改变绘图范围使其与数据相同,就不可能看到它们.
关于问题 2,不,使用 transform_points
不是必需的.cartopy 以这样一种方式设置,可以很容易地以最少的中间步骤绘制多个投影.如@swatchai所述,有时您可能希望使用实际的投影坐标,而使用 transform_points
方法将允许您执行此操作.当 transform_points
用于生成原始帖子中的第二个图时,它本质上是手动执行如果使用 PlateCarree
在 中正确处理输入坐标会自动完成的操作>转换
.
最后,@ajdawson 对绘图时如何使用 projection
和 transform
做出了重要说明.一旦您了解了源坐标的内容,此信息也很有用.该评论引述如下:
通常, projection
告诉cartopy绘制的地图应该是什么样子,而 transform
则告诉cartopy数据所代表的坐标系.您可以设置投影
到您喜欢的任何投影,但 transform
需要匹配您的数据使用的任何坐标系.
This question is in regards to plotting some data I have that uses the Lambert Conformal (LCC) CRS. While these questions specifically pertain to plotting LCC data in multiple projections, it also applies to the use of cartopy in general in that I would like to better understand the logic/process of plotting using cartopy.
Below are some code examples of what I am trying to do. The first example is simply plotting some LCC data. The data I used are available in the link 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()
The plot produced can be seen here:
US Dewpoints on LCC Map
My first confusion when using cartopy was why I always have to transform to PlateCarree
when plotting? My initial thought was the transform
keyword of the pcolormesh
call needed the LCC projection information and not PlateCarree
.
Next, if I want to plot my LCC data in another projection, e.g. Orthographic, would I go about doing so like below?
# 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()
The plot produced can be seen here:
US Dewpoints on Orthographic Map
I think the Orthographic map looks right, but I'd like to be sure that I understand the process of re-projection with cartopy correctly.
In summary, I would like to know the following things:
- Do you always have to
transform
toPlateCarree
when plotting? Why or why not? - Does re-projecting simply require a call to the
transform_points
method or are there other steps involved?
Update 1
Based on the answer from @swatchai, it seems as though the answer to my Question 2 is that transform_points
is not required. One can simply use the transform
keyword argument in many matplotlib plotting methods. This is what I thought originally. However, skipping the transform_points
has not worked for me. See example below:
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()
Which produces this plot:
Orthographic Plot Without transform_points Step
The problem appears to be that the lat and lon input does not get transformed into the grid coordinates so they only get plotted in an extremely small area of the plot. So, to expand upon Question 2, if you are supposed to skip transform_points
is there a bug in cartopy's plotting methods based on my above example? Or am I still missing a step?
An important distinction needs to be made between geographic and projected (or grid) coordinates. A more detailed description of those can be found here. The important thing, and what helps to answer Question 1, is that latitude and longitude are geographic coordinates whereas points that have units in meters are projected coordinates.
The numerical weather model where the example data came from uses the Lambert Conformal projection in its calculations (more here). However, the coordinates that get output are latitude and longitude. If you are inexperienced with spatial data, you can end up thinking that the lat/lon pairs are LCC projected coordinates when they are in fact geogrphic coordinates; the LCC stuff is used during model integration.
To answer Question 1, no, you do not always have to use PlateCarree
as the source CRS. You do, however, always use PlateCarree
for latitude and longitude data (which was the case here). This way cartopy will correctly transform your lat/lon values into projected coordinates (in meters) and be able to easily transform
your data to other projections during plotting. This issue is ultimately the reason for the seemingly blank plot in Update 1. By saying the source data have LCC projected coordinates in transform
, cartopy took the lat/lon input and interpreted them as having units of meters. The data did get plotted, but the extent was so small that it was impossible to see them without changing the plot extent to be the same as the data.
With regard to Question 2, no, using transform_points
is not a requirement. cartopy was set up in such a way to make is easy to plot in multiple projections with minimal intermediary steps. As @swatchai mentioned, sometimes you may want to use the actual projected coordinates and using the transform_points
method will allow you to do that. When transform_points
was used to produce the second plot in the original post it essentially was manually doing what would have automatically been done had the input coordinates been handled properly with PlateCarree
in transform
.
Finally, an important clarification was made by @ajdawson with regard to how to use projection
and transform
when plotting. Once you understand what you have for source coordinates, this information is also useful. The comment is quoted below:
In general,
projection
tells cartopy what the drawn map should look like, andtransform
tells cartopy what coordinate system your data is represented in. You can setprojection
to any projection you like, buttransform
needs to match whatever coordinate system your data uses.
这篇关于使用 cartopy 在其他投影仪中绘制投影数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!