matplotlib 使用Lambert投影绘制WRF数据的问题-未在数据顶部显示重叠线

3mpgtkmj  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(142)

我最近开始使用python通过jupyter在windows上绘制netCDF数据。然而,我在绘制使用Lambert Conformal投影的WRF运行的输出数据时遇到问题。我似乎无法将海岸线叠加并与数据图对齐,即海岸线叠加要么根本不显示,要么与数据略有偏移。这可能是由于数据的Lambert投影造成的吗引起问题?
下面是访问我使用的WRF输出nc文件的链接:https://drive.google.com/file/d/1s-0RLcaqIG0OoFEZtsE6_1xsE9B0DM1_/view?usp=sharing
我使用的代码的输出是附加的。

我似乎也无法在我使用的WRF输出文件上使用'Dataset',例如. ncfile = Dataset(“wrfout_d01_2016-10-07_00_00_00”)。这通常会导致以下错误:

  1. 61 lons = wrfnc.variables[lonvar][:]
  2. 663 # Need to check all times
  3. --> 664 for i in py3range(lats.shape[-3]):
  4. 665 start_idxs = [0] * len(lats.shape) # PyNIO does not support ndim
  5. 666 start_idxs[-3] = i

IndexError:tuple index out of range
我对这一切都很陌生,所以如果这些是愚蠢的问题,我道歉。
下面是我尝试使用的代码。任何帮助解决这个错误将不胜感激。

  1. from netCDF4 import Dataset
  2. import xarray as xr
  3. import matplotlib.pyplot as plt
  4. import cartopy.crs as ccrs
  5. ds = xr.open_dataset("output_mean.nc")
  6. temp2 = ds.T2[0,:,:]
  7. temp2
  8. fig = plt.figure(figsize=(5, 5))
  9. ax1 = plt.axes(projection=ccrs.LambertConformal())
  10. ax1.coastlines()
  11. temp2.plot(ax=ax1, cmap='jet', transform=ccrs.LambertConformal())
  12. ax1.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())
  13. ax1.coastlines()
  14. plt.show()
a64a0gku

a64a0gku1#

我认为还有一些不同的问题。避免使用Xarray数据集进行绘图可能会更清楚。为了方便起见,它通常是好的,但它也混淆了一些步骤,可能会增加这种情况下的混乱。看起来Xarray没有正确地选择坐标尺寸,如果你想直接使用Xarray数据集进行绘图,这可能需要一些修改。
我将从阅读Xarray对象到Numpy数组所需的数据开始:

  1. import xarray as xr
  2. import matplotlib.pyplot as plt
  3. import cartopy.crs as ccrs
  4. with xr.open_dataset("output_mean.nc") as ds:
  5. ds = ds.isel(Time=0) # strip the time dimension
  6. lons = ds["XLONG"].to_numpy()
  7. lats = ds["XLAT"].to_numpy()
  8. data = ds["T2"].to_numpy()

据我所知,坐标的投影并没有指定,但“WGS 84”或Cartopy中的ccrs.PlateCarree()通常是一个很好的猜测。
Cartopy中的默认LambertConformal与数据集中的数据具有不同的定义,您可以使用数据集中定义的值来指定相同的投影,它看起来应该是这样的:

  1. map_proj = ccrs.LambertConformal(
  2. central_latitude=39,
  3. central_longitude=-101,
  4. standard_parallels=(32, 46),
  5. )

如果你比较两者,你会注意到上面的定义并没有“扭曲”数据,与默认定义相比。如果数据在规则网格上,在同一个投影中绘制它可以避免在重新Map到不同投影时进行任何插值。这取决于需求是否需要。
有一件事你做错了,那就是指定LambertConformal作为数据的变换。但是使用Cartopy,你应该指定源数据的投影(你想要从源数据进行变换),它应该匹配你提供的坐标的投影,在这种情况下是纬度/经度坐标数组。目标投影,你想要变换到的地方,由轴的投影定义。

  1. fig, ax = plt.subplots(
  2. figsize=(8, 5), facecolor="w",
  3. subplot_kw=dict(projection=map_proj ),
  4. )
  5. cm = ax.pcolormesh(lons, lats, data, cmap='turbo', transform=ccrs.PlateCarree())
  6. cb = fig.colorbar(cm, ax=ax, shrink=.5)
  7. # ax.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())
  8. ax.coastlines()

如果省略设置范围,它将默认显示图中的所有数据:

使用LambertConformal()的默认定义会使其看起来像:

当然,在不同于输入数据的投影中绘图是完全有效的,但是在这样做时最好注意。
另一种方法是使用ax.imshow(假设它是一个规则的网格)绘图,这允许您按原样绘制数据(不需要重新投影),但这需要知道数据的范围。可能可以通过将角纬度/经度值重新投影到数据集中定义的投影来获得。

展开查看全部

相关问题