使用 Xarray 多文件数据集创建一堆图形

发布于 2025-01-15 13:45:02 字数 3740 浏览 3 评论 0原文

我有一堆 .grib 文件,我希望能够读取它们并为其创建图形。我有加载一个文件并绘制一个图形的代码,但我想找出循环它的最佳方法,这样我就不必更改每个文件的文件名和其他参数。到目前为止,我已从使用 xr.open_dataset 切换到 xr.open_mfdataset。我尝试使用 time 进行 For 循环,但在plot = ax.contourf 处出现错误,提示“TypeError:输入 Z 必须是 2D,而不是 3D。”数据集包含纬度、经度、t2m(2 米气温)和时间。请参阅下面的代码和附图。

ds=xr.open_mfdataset('./Data/ecmwf_dataset/t2m/*.grib', combine='nested', concat_dim='time',
                     engine='cfgrib',backend_kwargs={'indexpath': ''})

lons = ds['longitude'][:]
lats = ds['latitude'][:]
sfcT = ds['t2m']
time = ds['time'].dt.strftime('%m-%d-%Y')

for i in range(len(ds.time)):
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection=ccrs.NorthPolarStereo(central_longitude=-47))     

    ax.set_extent([-180, 180, 60, 90], crs=ccrs.PlateCarree())
    lon2d,lat2d = np.meshgrid(lons,lats)

    min_plot_value = -4
    max_plot_value = 4
    contour_interval = 1
    clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)

    plot = xr.plot.contourf(lon2d, lat2d, sfcT.isel(time=i), clevs, cmap=plt.cm.RdBu_r, 
                       extend='both', transform=ccrs.PlateCarree())

    resol = '50m'
    land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
      scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])

    plt.savefig('./Figures/ArcticT2mAnom_'+str(time.values)+'.png', facecolor='white', dpi=300)

输入图片此处描述

ValueError                                Traceback (most recent call last)
Input In [131], in <cell line: 1>()
     11 contour_interval = 1
     12 clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)
---> 14 plot = xr.plot.contourf(lon2d, lat2d, sfcT.isel(time=i),
     15                         clevs, cmap=plt.cm.RdBu_r, extend='both', transform=ccrs.PlateCarree())
     17 resol = '50m'  # use data at this scale
     18 land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
     19     scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/plot/plot.py:1132, in _plot2d.<locals>.newplotfunc(darray, x, y, figsize, size, aspect, ax, row, col, col_wrap, xincrease, yincrease, add_colorbar, add_labels, vmin, vmax, cmap, center, robust, extend, levels, infer_intervals, colors, subplot_kws, cbar_ax, cbar_kwargs, xscale, yscale, xticks, yticks, xlim, ylim, norm, **kwargs)
   1126 elif rgb is not None and not imshow_rgb:
   1127     raise ValueError(
   1128         'The "rgb" keyword is only valid for imshow()'
   1129         "with a three-dimensional array (per facet)"
   1130     )
-> 1132 xlab, ylab = _infer_xy_labels(
   1133     darray=darray, x=x, y=y, imshow=imshow_rgb, rgb=rgb
   1134 )
   1136 xval = darray[xlab]
   1137 yval = darray[ylab]

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/plot/utils.py:382, in _infer_xy_labels(darray, x, y, imshow, rgb)
    376 def _infer_xy_labels(darray, x, y, imshow=False, rgb=None):
    377     """
    378     Determine x and y labels. For use in _plot2d
    379 
    380     darray must be a 2 dimensional data array, or 3d for imshow only.
    381     """
--> 382     if (x is not None) and (x == y):
    383         raise ValueError("x and y cannot be equal.")
    385     if imshow and darray.ndim == 3:

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/core/common.py:136, in AbstractArray.__bool__(self)
    135 def __bool__(self: Any) -> bool:
--> 136     return bool(self.values)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I have a bunch of .grib files that I would like to be able to read in and create figures for. I have the code to load one file and plot a figure, but I'd like to figure out the best way to loop it so I don't have to change the filename and other parameters for each file. So far, I've switched from using xr.open_dataset to xr.open_mfdataset. I've tried doing a For Loop using time, but I get an error at plot = ax.contourf saying, "TypeError: Input Z must be 2D, not 3D." The dataset involves latitude, longitude, t2m (2-m air temperature), and time. See below code and attached image.

ds=xr.open_mfdataset('./Data/ecmwf_dataset/t2m/*.grib', combine='nested', concat_dim='time',
                     engine='cfgrib',backend_kwargs={'indexpath': ''})

lons = ds['longitude'][:]
lats = ds['latitude'][:]
sfcT = ds['t2m']
time = ds['time'].dt.strftime('%m-%d-%Y')

for i in range(len(ds.time)):
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection=ccrs.NorthPolarStereo(central_longitude=-47))     

    ax.set_extent([-180, 180, 60, 90], crs=ccrs.PlateCarree())
    lon2d,lat2d = np.meshgrid(lons,lats)

    min_plot_value = -4
    max_plot_value = 4
    contour_interval = 1
    clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)

    plot = xr.plot.contourf(lon2d, lat2d, sfcT.isel(time=i), clevs, cmap=plt.cm.RdBu_r, 
                       extend='both', transform=ccrs.PlateCarree())

    resol = '50m'
    land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
      scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])

    plt.savefig('./Figures/ArcticT2mAnom_'+str(time.values)+'.png', facecolor='white', dpi=300)

enter image description here

ValueError                                Traceback (most recent call last)
Input In [131], in <cell line: 1>()
     11 contour_interval = 1
     12 clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)
---> 14 plot = xr.plot.contourf(lon2d, lat2d, sfcT.isel(time=i),
     15                         clevs, cmap=plt.cm.RdBu_r, extend='both', transform=ccrs.PlateCarree())
     17 resol = '50m'  # use data at this scale
     18 land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
     19     scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/plot/plot.py:1132, in _plot2d.<locals>.newplotfunc(darray, x, y, figsize, size, aspect, ax, row, col, col_wrap, xincrease, yincrease, add_colorbar, add_labels, vmin, vmax, cmap, center, robust, extend, levels, infer_intervals, colors, subplot_kws, cbar_ax, cbar_kwargs, xscale, yscale, xticks, yticks, xlim, ylim, norm, **kwargs)
   1126 elif rgb is not None and not imshow_rgb:
   1127     raise ValueError(
   1128         'The "rgb" keyword is only valid for imshow()'
   1129         "with a three-dimensional array (per facet)"
   1130     )
-> 1132 xlab, ylab = _infer_xy_labels(
   1133     darray=darray, x=x, y=y, imshow=imshow_rgb, rgb=rgb
   1134 )
   1136 xval = darray[xlab]
   1137 yval = darray[ylab]

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/plot/utils.py:382, in _infer_xy_labels(darray, x, y, imshow, rgb)
    376 def _infer_xy_labels(darray, x, y, imshow=False, rgb=None):
    377     """
    378     Determine x and y labels. For use in _plot2d
    379 
    380     darray must be a 2 dimensional data array, or 3d for imshow only.
    381     """
--> 382     if (x is not None) and (x == y):
    383         raise ValueError("x and y cannot be equal.")
    385     if imshow and darray.ndim == 3:

File ~/opt/anaconda3/lib/python3.8/site-packages/xarray/core/common.py:136, in AbstractArray.__bool__(self)
    135 def __bool__(self: Any) -> bool:
--> 136     return bool(self.values)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑看君怀她人 2025-01-22 13:45:02

我的代码在进行这些更改后可以工作:“for i in range(len(ds.time)):”和“sfcT.isel(time=i)”

ds=xr.open_mfdataset('./Data/ecmwf_dataset/t2m/*.grib', combine='nested', concat_dim='time',
                     engine='cfgrib',backend_kwargs={'indexpath': ''})

lons = ds['longitude'][:]
lats = ds['latitude'][:]
sfcT = ds['t2m']
time = ds['time'].dt.strftime('%m-%d-%Y')

for i in range(len(ds.time)):
    fig = plt.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection=ccrs.NorthPolarStereo(central_longitude=-47))
    ax.set_extent([-180, 180, 60, 90], crs=ccrs.PlateCarree())
    
    lon2d,lat2d = np.meshgrid(lons,lats)
 
    
    min_plot_value = -4
    max_plot_value = 4
    contour_interval = 1
    clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)

    plot = ax.contourf(lon2d, lat2d, sfcT.isel(time=i),
                            clevs, cmap=plt.cm.RdBu_r, extend='both', transform=ccrs.PlateCarree())

    resol = '50m'  # use data at this scale
    land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
        scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])

My code works after making these changes: "for i in range(len(ds.time)):" and "sfcT.isel(time=i)"

ds=xr.open_mfdataset('./Data/ecmwf_dataset/t2m/*.grib', combine='nested', concat_dim='time',
                     engine='cfgrib',backend_kwargs={'indexpath': ''})

lons = ds['longitude'][:]
lats = ds['latitude'][:]
sfcT = ds['t2m']
time = ds['time'].dt.strftime('%m-%d-%Y')

for i in range(len(ds.time)):
    fig = plt.figure(figsize=(10,10))
    ax = fig.add_subplot(111, projection=ccrs.NorthPolarStereo(central_longitude=-47))
    ax.set_extent([-180, 180, 60, 90], crs=ccrs.PlateCarree())
    
    lon2d,lat2d = np.meshgrid(lons,lats)
 
    
    min_plot_value = -4
    max_plot_value = 4
    contour_interval = 1
    clevs = np.arange(min_plot_value,max_plot_value+1,contour_interval)

    plot = ax.contourf(lon2d, lat2d, sfcT.isel(time=i),
                            clevs, cmap=plt.cm.RdBu_r, extend='both', transform=ccrs.PlateCarree())

    resol = '50m'  # use data at this scale
    land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
        scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文