【问题标题】:How to adjust Matplotlib colorbar range in xarray plot?如何在 xarray 图中调整 Matplotlib 颜色条范围?
【发布时间】:2021-10-08 01:30:05
【问题描述】:

我有一个看起来像这样的情节

我不明白如何手动更改或设置颜色条的数据值范围。我想根据图中显示的数据值试验范围并将颜色条更改为(-4,4)。我看到plt.climvminvmax 是可能使用的函数。

这是我的代码:

import cdsapi
import xarray as xr
import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
# Also requires cfgrib library.

c = cdsapi.Client()

url = c.retrieve(
    'reanalysis-era5-single-levels-monthly-means',
    {
        'product_type': 'monthly_averaged_reanalysis',
        'format': 'grib',
        'variable': ['100m_u_component_of_wind','100m_v_component_of_wind'],
        'year': ['2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018','2019','2020','2021'],
        'month': ['01','02','03','04','05','06','07','08','09','10','11','12'],
        'time': '00:00',
        'grid': [0.25, 0.25],
        'area': [70.00, -180.00, -40.00, 180.00],
    },
    "C:\\Users\\U321103\\.spyder-py3\\ERA5_MAPPING\\100m_wind_U_V.grib")
path = "C:\\Users\\U321103\\.spyder-py3\\ERA5_MAPPING\\100m_wind_U_V.grib"
ds = xr.load_dataset(path, engine='cfgrib')

wind_abs = np.sqrt(ds.u100**2 + ds.v100**2)
monthly_means = wind_abs.mean(dim='time')
wind_abs_clim = wind_abs.sel(time=slice('2006-01','2020-12')).groupby('time.month').mean(dim='time') # select averaging period

wind_abs_anom = ((wind_abs.groupby('time.month') / wind_abs_clim))-1 #deviation from climo

fg = wind_abs_anom.sel(time=slice('2021-01',None)).groupby('time.month').mean(dim='time').plot(col='month',
                        col_wrap=3,transform=ccrs.PlateCarree(),
                        cbar_kwargs={'orientation':'horizontal','shrink':0.6, 'aspect':40,'label':'Percent Deviation'},robust=False,subplot_kws={'projection': ccrs.Mercator()})

fg.map(lambda: plt.gca().coastlines())                                                                                               

【问题讨论】:

    标签: python matplotlib python-xarray colorbar


    【解决方案1】:

    我能够重现你的图,发现我可以添加vminvmax,如下所示。出于某种原因,这意味着我还必须指定颜色图,否则我最终会得到viridis。但是下面的代码对我有用(在我让它工作时进行了一些重构——这里唯一的重大变化是在底部的绘图部分)。

    首先,加载数据:

    import cdsapi
    
    c = cdsapi.Client()
    params = {
        'product_type': 'monthly_averaged_reanalysis',
        'format': 'grib',
        'variable': ['100m_u_component_of_wind', '100m_v_component_of_wind'],
        'year': [f'{n}' for n in range(2006, 2022)],
        'month': [f'{n:02d}' for n in range(1, 13)],
        'time': '00:00',
        'grid': [0.25, 0.25],
        'area': [70.00, -180.00, -40.00, 180.00],
    }
    path = '100m_wind_U_V.grib'
    url = c.retrieve('reanalysis-era5-single-levels-monthly-means',
                     params,
                     path,
                    )
    

    然后是数据管道:

    import xarray as xr
    import numpy as np
    # Also need cfgrib library.
    
    ds = xr.load_dataset(path, engine='cfgrib')
    wind_abs = np.sqrt(ds.u100**2 + ds.v100**2)
    monthly_means = wind_abs.mean(dim='time')
    wind_abs_clim = (wind_abs.sel(time=slice('2006-01','2020-12'))
                             .groupby('time.month')
                             .mean(dim='time'))
    wind_abs_anom = ((wind_abs.groupby('time.month') / wind_abs_clim)) - 1
    

    终于出图了:

    import cartopy.crs as ccrs
    import matplotlib.pyplot as plt
    
    cbar_kwargs = {'orientation':'horizontal', 'shrink':0.6, 'aspect':40, 'label':'Percent Deviation'}
    subplot_kws = {'projection': ccrs.Mercator()}
    fg = (wind_abs_anom.sel(time=slice('2021-01', None))
                       .groupby('time.month')
                       .mean(dim='time')
                       .plot(col='month',
                             col_wrap=3,
                             transform=ccrs.PlateCarree(),
                             cmap='RdBu_r', vmin=-3, vmax=3,  # <-- New bit.
                             cbar_kwargs=cbar_kwargs,
                             robust=False,
                             subplot_kws=subplot_kws
                            ))
    fg.map(lambda: plt.gca().coastlines())
    

    有时我会使用百分位数来自动控制vminvmax 的值,例如max_ = np.percentile(data, 99),然后是vmin=-max_, vmax=max_。这很好地处理了拉伸颜色图的异常值,但它要求您能够在绘制图之前计算这些值。

    如果您想开始对绘图有更多控制权,最好停止使用xarray 绘图界面并直接使用matplotlibcartopy。下面是它的样子(替换上面的所有绘图代码):

    import cartopy.crs as ccrs
    import matplotlib.pyplot as plt
    
    sel = wind_abs_anom.sel(time=slice('2021-01', None))
    
    left, *_, right = wind_abs_anom.longitude
    top, *_, bottom = wind_abs_anom.latitude  # Min and max latitude.
    extent = [left, right, bottom, top]
    
    fig, axs = plt.subplots(nrows=2, ncols=3,
                            figsize=(15, 6),
                            subplot_kw={'projection': ccrs.PlateCarree()},
                           )
    
    for ax, (month, group) in zip(axs.flat, sel.groupby('time.month')):
        mean = group.mean(dim='time')
        im = ax.imshow(mean,
                       transform=ccrs.PlateCarree(),
                       extent=extent,
                       cmap='RdBu_r', vmin=-3, vmax=3)
        ax.set_title(f'month = {month}')
        ax.coastlines()
    
    cbar_ax = fig.add_axes([0.2, 0.0, 0.6, 0.05])  # Left, bottom, width, height.
    cbar = fig.colorbar(im, cax=cbar_ax, extend='both', orientation='horizontal')
    cbar.set_label('Percent deviation')
        
    plt.show()
    

    由于某种原因,当我尝试将ccra.Mercator() 用于地图时,数据会失真;也许你可以弄清楚这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2022-07-05
      • 2017-04-20
      相关资源
      最近更新 更多