def draw_wind_rh_according_to_4D_data(sta_fcs_fcst=None,
                                      zd_fcst_obs=None,
                                      fcst_info=None,
                                      map_extent=(50, 150, 0, 65),
                                      bkgd_type='satellite',
                                      bkgd_level=None,
                                      draw_zd=True,
                                      output_dir=None):

    # set font
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)
    # set figure
    plt.figure(figsize=(16, 9))

    plotcrs = ccrs.PlateCarree()
    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)
    if (bkgd_type == 'satellite'):
        c_city_names = 'w'
        c_sta_fcst = 'w'
        c_tile_str = '白色'
    else:
        c_city_names = 'black'
        c_sta_fcst = 'black'
        c_tile_str = '黑色'

    datacrs = ccrs.PlateCarree()

    ax.set_extent(map_extent, crs=datacrs)

    # draw data
    plots = {}

    if (bkgd_type == 'satellite'):
        request = utl.TDT_img()  #卫星图像
    if (bkgd_type == 'terrain'):
        request = utl.TDT_ter()  #卫星图像
    if (bkgd_type == 'road'):
        request = utl.TDT()  #卫星图像

    ax.add_image(request, bkgd_level)  # level=10 缩放等级

    #cmap=dk_ctables.cm_thetae()
    plots['t2m'] = ax.scatter(sta_fcs_fcst['lon'],
                              sta_fcs_fcst['lat'],
                              s=1400,
                              c='white',
                              alpha=1,
                              zorder=120)
    cmap, norm = dk_ctables.cm_relative_humidity_nws()
    cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)
    plots['t2m'] = ax.scatter(sta_fcs_fcst['lon'],
                              sta_fcs_fcst['lat'],
                              s=1300,
                              c=sta_fcs_fcst['RH'],
                              vmin=0,
                              vmax=100,
                              cmap=cmap,
                              alpha=1,
                              zorder=120)

    for ista in range(0, len(sta_fcs_fcst['lon'])):
        city_names = sta_fcs_fcst['name'][ista]
        ax.text(sta_fcs_fcst['lon'][ista] - 0.001,
                sta_fcs_fcst['lat'][ista],
                city_names + '  ',
                family='SimHei',
                ha='right',
                va='center',
                size=20,
                color=c_city_names,
                zorder=140)
        ax.text(sta_fcs_fcst['lon'][ista],
                sta_fcs_fcst['lat'][ista],
                '%i' % sta_fcs_fcst['RH'][ista],
                family='SimHei',
                size=20,
                color='white',
                zorder=140,
                ha='center',
                va='center')
    plots['uv'] = ax.barbs(np.array(sta_fcs_fcst['lon']) - 0.001,
                           np.array(sta_fcs_fcst['lat']),
                           sta_fcs_fcst['U'],
                           sta_fcs_fcst['V'],
                           barb_increments={
                               'half': 2,
                               'full': 4,
                               'flag': 20
                           },
                           length=12,
                           linewidth=6,
                           transform=datacrs,
                           fill_empty=False,
                           sizes=dict(emptybarb=0.01),
                           zorder=130,
                           color='white')

    plots['uv'] = ax.barbs(np.array(sta_fcs_fcst['lon']) - 0.001,
                           np.array(sta_fcs_fcst['lat']),
                           sta_fcs_fcst['U'],
                           sta_fcs_fcst['V'],
                           barb_increments={
                               'half': 2,
                               'full': 4,
                               'flag': 20
                           },
                           length=12,
                           linewidth=3,
                           transform=datacrs,
                           fill_empty=False,
                           sizes=dict(emptybarb=0.01),
                           zorder=130,
                           color='black')

    if (draw_zd is True):
        plots['uv'] = ax.barbs(zd_fcst_obs['lon'],
                               zd_fcst_obs['lat'],
                               zd_fcst_obs['U'],
                               zd_fcst_obs['V'],
                               barb_increments={
                                   'half': 2,
                                   'full': 4,
                                   'flag': 20
                               },
                               length=7,
                               linewidth=2,
                               transform=datacrs,
                               fill_empty=False,
                               sizes=dict(emptybarb=0.01),
                               zorder=100,
                               color=c_sta_fcst,
                               alpha=0.7)

        if (zd_fcst_obs['obs_valid'] is True):
            plots['uv'] = ax.barbs(zd_fcst_obs['lon'],
                                   zd_fcst_obs['lat'],
                                   zd_fcst_obs['U_obs'],
                                   zd_fcst_obs['V_obs'],
                                   barb_increments={
                                       'half': 2,
                                       'full': 4,
                                       'flag': 20
                                   },
                                   length=8,
                                   linewidth=1.5,
                                   transform=datacrs,
                                   fill_empty=False,
                                   sizes=dict(emptybarb=0.01),
                                   zorder=100,
                                   color='red',
                                   alpha=0.7)


#additional information
    plt.title('基于EC模式降尺度预报 ' + '10米风(红色实况,' + c_tile_str + '预报), ' +
              '相对湿度(圆形填色及数字)',
              loc='left',
              fontsize=20)

    l, b, w, h = ax.get_position().bounds

    bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(
        str(fcst_info['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(
        hours=fcst_info['forecast_period'].values[0])
    #发布时间
    if (sys.platform[0:3] == 'lin'):
        locale.setlocale(locale.LC_CTYPE, 'zh_CN')
    if (sys.platform[0:3] == 'win'):
        locale.setlocale(locale.LC_CTYPE, 'chinese')
    plt.text(2.5,
             7.5,
             '起报时间: ' + initial_time.strftime("%Y年%m月%d日%H时"),
             size=15)
    plt.text(2.5, 5, '预报时间: ' + fcst_time.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(2.5,
             2.5,
             '预报时效: ' + str(int(fcst_info['forecast_period'].values)) + '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add logo
    utl.add_logo_extra_in_axes(pos=[l - 0.02, b + h - 0.1, .1, .1],
                               which='nmc',
                               size='Xlarge')

    # add color bar
    cax = plt.axes([0.25, 0.06, .5, .02])
    cb = plt.colorbar(plots['t2m'], cax=cax, orientation='horizontal')
    cb.ax.tick_params(labelsize='x-large')
    cb.set_label('相对湿度 (%)', size=20)

    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + 'BSEP_NMC_RFFC_ECMWF_EME_ASC_LNO_P9_' +
                    initial_time.strftime("%Y%m%d%H") + '00' +
                    str(int(fcst_info['forecast_period'].values[0])).zfill(3) +
                    '03.jpg',
                    dpi=200,
                    bbox_inches='tight')

    if (output_dir == None):
        plt.show()
def draw_gh_uv_rh(gh=None, uv=None, rh=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,city=True,south_China_sea=True,
                    output_dir=None,Global=False):

    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

    # draw figure
    plt.figure(figsize=(16,9))

    # set data projection
    if(Global == True):
        plotcrs = ccrs.Robinson(central_longitude=115.)
    else:
        plotcrs = ccrs.AlbersEqualArea(central_latitude=(map_extent[2]+map_extent[3])/2., 
            central_longitude=(map_extent[0]+map_extent[1])/2., standard_parallels=[30., 60.])
 
    ax = plt.axes([0.01,0.1,.98,.84], projection=plotcrs)
    
    plt.title('['+gh.attrs['model']+'] '+
    str(int(gh['level']))+'hPa 位势高度场, '+
    str(int(uv['level']))+'hPa 风场, '+
    str(int(rh['level']))+'hPa 相对湿度', 
        loc='left', fontsize=30)
        
    datacrs = ccrs.PlateCarree()

    #adapt to the map ratio
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)
    #adapt to the map ratio

    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(
        ax, name='coastline', edgecolor='gray', lw=0.8, zorder=5,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=5)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=5)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=5,alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if rh is not None:
        x, y = np.meshgrid(rh['lon'], rh['lat'])
        z=np.squeeze(rh['data'])
        cmap,norm=dk_ctables.cm_relative_humidity_nws()
        cmap.set_under(color=[0,0,0,0],alpha=0.0)

        plots['rh'] = ax.pcolormesh(
            x, y, z, norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)

    # draw -hPa wind bards
    if uv is not None:
        x, y = np.meshgrid(uv['lon'], uv['lat'])
        u = np.squeeze(uv['u']) * 2.5
        v = np.squeeze(uv['v']) * 2.5
        plots['uv'] = ax.barbs(
            x, y, u.values, v.values, length=6, regrid_shape=regrid_shape,
            transform=datacrs, fill_empty=False, sizes=dict(emptybarb=0.05),
            zorder=2)

    # draw -hPa geopotential height
    if gh is not None:
        x, y = np.meshgrid(gh['lon'], gh['lat'])
        clevs_gh = np.append(np.append(np.arange(0, 480, 4),np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))), np.arange(604, 2000, 8))
        plots['gh'] = ax.contour(
            x, y, np.squeeze(gh['data']), clevs_gh, colors='black',
            linewidths=2, transform=datacrs, zorder=3)
        plt.clabel(plots['gh'], inline=1, fontsize=20, fmt='%.0f',colors='black')

    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=4)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    utl.add_cartopy_background(ax,name='RD')

    l, b, w, h = ax.get_position().bounds
    #forecast information
    bax=plt.axes([l,b+h-0.1,.25,.1],facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(
    str(gh['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=gh['forecast_period'].values[0])
    #发布时间
    if(sys.platform[0:3] == 'lin'):
        locale.setlocale(locale.LC_CTYPE, 'zh_CN.utf8')
    if(sys.platform[0:3] == 'win'):        
        locale.setlocale(locale.LC_CTYPE, 'chinese')
    plt.text(2.5, 7.5,'起报时间: '+initTime.strftime("%Y年%m月%d日%H时"),size=15)
    plt.text(2.5, 5,'预报时间: '+fcst_time.strftime("%Y年%m月%d日%H时"),size=15)
    plt.text(2.5, 2.5,'预报时效: '+str(int(gh['forecast_period'].values[0]))+'小时',size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    if(rh != None):
        cax=plt.axes([l,b-0.04,w,.02])
        cb = plt.colorbar(plots['rh'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label('Relative Humidity (%)',size=20)

    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[l+w-0.091,b,.1,.2])

    small_city=False
    if(map_extent2[1]-map_extent2[0] < 25):
        small_city=True
    if city:
        utl.add_city_on_map(ax,map_extent=map_extent2,transform=datacrs,zorder=5,size=13,small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[l-0.02,b+h-0.1,.1,.1],which='nmc', size='Xlarge')

    # show figure
    if(output_dir != None):
        plt.savefig(output_dir+'位势高度场_风场_相对湿度_预报_'+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(gh['forecast_period'].values[0])+'小时'+'.png', dpi=200)
    
    if(output_dir == None):
        plt.show()