def draw_Crosssection_Wind_Theta_e_div(
                    cross_div3d=None, cross_Theta_e=None, cross_u=None,
                    cross_v=None,cross_terrain=None,
                    gh=None,
                    h_pos=None,st_point=None,ed_point=None,
                    levels=None,map_extent=(50, 150, 0, 65),lw_ratio=None,
                    output_dir=None):

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

    initTime = pd.to_datetime(
    str(cross_Theta_e['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=gh['forecast_period'].values[0])
    
    fig = plt.figure(1, figsize=(lw_ratio[0], lw_ratio[1]))
    ax = plt.axes()
    absv_contour = ax.contourf(cross_div3d['lon'], cross_div3d['level'], cross_div3d['data']*1e6,
                        levels=range(-100, 100, 1), cmap=dk_ctables2.ncl_cmaps('GMT_haxby'),extend='both')
    absv_colorbar = fig.colorbar(absv_contour)

    # Plot potential temperature using contour, with some custom labeling
    Theta_e_contour = ax.contour(cross_Theta_e['lon'], cross_Theta_e['level'],cross_Theta_e.values,
                            levels=np.arange(250, 450, 5), colors='k', linewidths=2)

    Theta_e_contour.clabel(np.arange(250, 450, 5), fontsize=20, colors='k', inline=1,
                        inline_spacing=8, fmt='%i', rightside_up=True, use_clabeltext=True)

    wind_slc_vert = list(range(0, len(levels), 1))
    wind_slc_horz = slice(5, 100, 5)
    ax.barbs(cross_u['lon'][wind_slc_horz], cross_u['level'][wind_slc_vert],
            cross_u['t_wind'][wind_slc_vert, wind_slc_horz]*2.5,    
            cross_v['n_wind'][wind_slc_vert, wind_slc_horz]*2.5, color='k')

    startcolor = '#8B4513'   #棕色
    endcolor='#DAC2AD' #绿 
    cmap2 = col.LinearSegmentedColormap.from_list('own3',[endcolor,startcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)
    terrain_contour = ax.contourf(cross_terrain['lon'], cross_terrain['level'], cross_terrain.values,
                            levels=np.arange(0, 500, 1), cmap=cm.get_cmap('own3'),zorder=100)

    # Adjust the y-axis to be logarithmic
    ax.set_yscale('symlog')
    ax.set_yticklabels(np.arange(levels[0], levels[-1], -100))
    ax.set_ylim(levels[0], levels[-1])
    ax.set_yticks(np.arange(levels[0], levels[-1], -100))

    # Define the CRS and inset axes
    data_crs = ccrs.PlateCarree()
    ax_inset = fig.add_axes(h_pos, projection=data_crs)
    ax_inset.set_extent(map_extent, crs=data_crs)
    # Plot geopotential height at 500 hPa using xarray's contour wrapper
    ax_inset.contour(gh['lon'], gh['lat'], np.squeeze(gh['data']),
                    levels=np.arange(500, 600, 4), cmap='inferno')
    # Plot the path of the cross section
    endpoints = data_crs.transform_points(ccrs.Geodetic(),
                                        *np.vstack([st_point, ed_point]).transpose()[::-1])
    ax_inset.scatter(endpoints[:, 0], endpoints[:, 1], c='k', zorder=2)
    ax_inset.plot(cross_u['lon'], cross_u['lat'], c='k', zorder=2)
    # Add geographic features
    ax_inset.coastlines()
    utl.add_china_map_2cartopy_public(
            ax_inset, name='province', edgecolor='black', lw=0.8, zorder=105)
    # Set the titles and axes labels
    ax_inset.set_title('')

    ax.set_title('相当位温, 水平散度, 沿剖面风', loc='right', fontsize=20)
    ax.set_ylabel('Pressure (hPa)')
    ax.set_xlabel('Longitude')
    absv_colorbar.set_label('水平散度 (dimensionless)')

    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')
    bax=fig.add_axes([0.10,0.88,.25,.07],facecolor='#FFFFFFCC')
    bax.axis('off')
    #bax.set_yticks([])
    #bax.set_xticks([])
    bax.axis([0, 10, 0, 10])        
    plt.text(2.5, 7.5,'起报时间: '+initTime.strftime("%Y年%m月%d日%H时"),size=11)
    plt.text(2.5, 5,'预报时间: '+fcst_time.strftime("%Y年%m月%d日%H时"),size=11)
    plt.text(2.5, 2.5,'预报时效: '+str(int(gh['forecast_period'].values[0]))+'小时',size=11)
    plt.text(2.5, 0.5,'www.nmc.cn',size=11)

    utl.add_logo_extra_in_axes(pos=[0.1,0.88,.07,.07],which='nmc', size='Xlarge')

    # show figure
    if(output_dir != None):
        plt.savefig(output_dir+'相当位温_水平散度_沿剖面风_预报_'+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(int(gh['forecast_period'].values[0]))+'小时'+'.png', dpi=200,bbox_inches='tight')
        plt.close()
    
    if(output_dir == None):
        plt.show() 
Beispiel #2
0
def draw_isentropic_uv(isentrh=None, isentuv=None, isentprs=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,city=False,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('['+isentrh['model']+'] '+
    isentrh['lev']+'等熵面  风场 相对湿度 气压', 
        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=105,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=105)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=105)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=105,alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if isentrh is not None:

        x, y = np.meshgrid(isentrh['lon'], isentrh['lat'])
        z=np.squeeze(isentrh['data'])
        clevs_rh= range(10, 106, 5)
        plots['isentrh'] = ax.contourf(
            x, y, z,clevs_rh,cmap=plt.cm.gist_earth_r,
            transform=datacrs,alpha=0.5,extend='both')

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

    # draw -hPa geopotential height
    if isentprs is not None:
        x, y = np.meshgrid(isentprs['lon'], isentprs['lat'])
        clevs_isentprs =  np.arange(0, 1000, 25)
        z=gaussian_filter(np.squeeze(isentprs['data']),5)
        plots['isentprs'] = ax.contour(
            x, y, z , clevs_isentprs, colors='black',
            linewidths=2, transform=datacrs, zorder=30)
        plt.clabel(plots['isentprs'], inline=1, fontsize=20, fmt='%.0f',colors='black')

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

    #http://earthpy.org/cartopy_backgroung.html
    #C:\ProgramData\Anaconda3\Lib\site-packages\cartopy\data\raster\natural_earth
    ax.background_img(name='RD', resolution='high')

    #forecast information
    bax=plt.axes([0.01,0.835,.25,.1],facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(
    str(isentrh['init_time'])).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=isentrh['fhour'])
    #发布时间
    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(isentrh['fhour'])+'小时',size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    if(isentrh != None):
        cax=plt.axes([0.11,0.06,.86,.02])
        cb = plt.colorbar(plots['isentrh'], cax=cax, orientation='horizontal',
                      ticks=clevs_rh[:],
                      extend='both',extendrect=False)
        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=[0.85,0.13,.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=110,size=13,small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[-0.01,0.835,.1,.1],which='nmc', size='Xlarge')

    # show figure
    if(output_dir != None):
        plt.savefig(output_dir+isentrh['lev']+'等熵面分析_相对湿度_风场_气压_预报_'+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(isentrh['fhour'])+'小时'+'.png', dpi=200)
    
    if(output_dir == None):
        plt.show()              
Beispiel #3
0
def Horizontal_Pallete(figsize=(16, 9),
                       plotcrs=ccrs.PlateCarree(),
                       datacrs=ccrs.PlateCarree(),
                       map_extent=(60, 145, 15, 55),
                       title='',
                       forcast_info='',
                       add_china=True,
                       add_city=False,
                       add_background=True,
                       south_China_sea=True,
                       info_zorder=10,
                       title_fontsize=30):

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

    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')

    fig = plt.figure(figsize=figsize)
    if (plotcrs is None):
        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)
    #ax.set_extent(map_extent, crs=crs)
    map_extent = adjust_map_ratio(ax, map_extent=map_extent, datacrs=datacrs)
    plt.title(title, loc='left', fontsize=title_fontsize)
    # add grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=info_zorder)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

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

    if add_city:
        small_city = False
        if (map_extent[1] - map_extent[0] < 25):
            small_city = True
        utl.add_city_on_map(ax,
                            map_extent=map_extent,
                            size=12,
                            transform=datacrs,
                            zorder=info_zorder + 1,
                            small_city=small_city)

    if add_background:
        ax.add_feature(cfeature.OCEAN)
        utl.add_cartopy_background(ax, name='RD')

    if south_China_sea:
        l, b, w, h = ax.get_position().bounds
        utl.add_south_China_sea(pos=[l + w - 0.0875, b, .1, .2])

    if forcast_info:
        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])
        bax.text(
            2.2,
            9.8,
            forcast_info,
            size=15,
            va='top',
            ha='left',
        )

    l, b, w, h = ax.get_position().bounds
    utl.add_logo_extra_in_axes(pos=[l - 0.022, b + h - 0.1, .1, .1],
                               which='nmc',
                               size='Xlarge')

    return fig, ax, map_extent
Beispiel #4
0
def draw_gh_rain(gh=None, rain=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,city=True,south_China_sea=True,
                    output_dir=None,Global=False):
# set font
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

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

    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.])
 
    datacrs = ccrs.PlateCarree()

    ax = plt.axes([0.01,0.1,.98,.84], projection=plotcrs)
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if rain is not None:
        x, y = np.meshgrid(rain['lon'], rain['lat'])
        z=np.squeeze(rain['data'].values)
        z[z<0.1]=np.nan
        cmap,norm=dk_ctables.cm_qpf_nws(atime=rain.attrs['atime'])
        cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['rain'] = ax.pcolormesh(
            x,y,z, norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)

    # 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=2, fontsize=20, fmt='%.0f',colors='black')
#additional information
    plt.title('['+gh.attrs['model']+'] '+
    str(int(gh['level'].values[0]))+'hPa 位势高度场, '+
    str(int(rain.attrs['atime']))+'小时降水', 
        loc='left', fontsize=30)
        
    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(
        ax, name='coastline', edgecolor='gray', lw=0.8, zorder=3,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=3)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=3)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=3,alpha=0.5)


    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=1)
    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.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=gh.coords['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.coords['forecast_period'].values[0]))+'小时'+'(降水'+str(int(gh.coords['forecast_period'].values[0]+12))+'小时)',size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    if(rain != None):
        cax=plt.axes([l,b-0.04,w,.02])
        cb = plt.colorbar(plots['rain'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label(str(int(rain.attrs['atime']))+'h precipitation (mm)',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=2,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(int(gh.coords['forecast_period'].values[0]))+'小时'+'.png', dpi=200)
    
    if(output_dir == None):
        plt.show()
Beispiel #5
0
def draw_cumulated_precip_evo(
        rain=None,
        map_extent=(50, 150, 0, 65),
        regrid_shape=20,
        add_china=True,city=True,south_China_sea=True,
        output_dir=None,Global=False):
# set font
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

# set figure
    fig = plt.figure(figsize=(16,9))

    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.])

    datacrs = ccrs.PlateCarree()

    ax = plt.axes([0.01,0.1,.98,.84], projection=plotcrs)
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if rain is not None:
        x, y = np.meshgrid(rain['lon'], rain['lat'])
        z=np.squeeze(rain['data'].values)
        z[z<0.1]=np.nan
        znan=np.zeros(shape=x.shape)
        znan[:]=np.nan
        cmap,norm=dk_ctables.cm_qpf_nws(atime=24)
        cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['rain'] = ax.pcolormesh(
            x,y,znan, norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)
#additional information
    plt.title('['+rain.attrs['model']+'] '+
    str(int(rain.coords['forecast_period'].values[0])-rain.attrs['t_gap'])+
        '至'+str(int(rain.coords['forecast_period'].values[-1]))+'时效累积降水预报',
        loc='left', fontsize=25)

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

    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=1)
    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


    initTime = pd.to_datetime(
    str(rain.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()

    #发布时间
    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')

    # add color bar
    cax=plt.axes([l,b-0.04,w,.02])
    cb = plt.colorbar(plots['rain'], cax=cax, orientation='horizontal')
    cb.ax.tick_params(labelsize='x-large')                      
    cb.set_label('Precipitation (mm)',size=20)
    fcst_time=initTime+timedelta(hours=rain.coords['forecast_period'].values[0])
    bax=plt.axes([l,b+h-0.1,.25,.1])
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])   
    fcst_time1=initTime+timedelta(hours=rain.coords['forecast_period'].values[0]-6)
    bax.text(2.5, 7.5,'起始时间: '+fcst_time1.strftime("%Y年%m月%d日%H时"),size=15)
    bax.text(2.5, 0.5,'www.nmc.cn',size=15)
    valid_fhour=bax.text(2.5, 5,'截至时间: ',size=15)
    txt_fhour=bax.text(2.5, 2.5,'预报时效: ',size=15)
    utl.add_logo_extra_in_axes(pos=[l-0.02,b+h-0.1,.1,.1],which='nmc', size='Xlarge')
    # 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=2,size=13,small_city=small_city)

    def update(frame_number):
        fcst_time2=initTime+timedelta(hours=rain.coords['forecast_period'].values[frame_number])
        valid_fhour.set_text('截至时间: '+fcst_time2.strftime("%Y年%m月%d日%H时"))
        txt_fhour.set_text('预报时效: '+str(int(rain.coords['forecast_period'].values[frame_number]))+'小时')
        return ax.pcolormesh(
            x,y,np.squeeze(z[frame_number,:,:]), norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)
    nframes=rain['data'].shape[0]
    animation1 = FuncAnimation(fig, update, frames=nframes,interval=1000)
    # ffmpegpath = os.path.abspath(r"C:\Users\HEYGY\Desktop\ffmpeg-20200824-3477feb-win64-static\bin\ffmpeg.exe")
    # import matplotlib
    # matplotlib.rcParams["animation.ffmpeg_path"] = ffmpegpath
    # writer = animation.FFMpegWriter()
    # show figure
    plt.subplots_adjust(top=1, bottom=0, right=0.93, left=0, hspace=0, wspace=0)
    plt.margins(0, 0)
    if(output_dir != None):
        animation1.save(output_dir+'累积降水演变_'+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(int(rain.coords['forecast_period'].values[-1]))+'小时_'+
        '['+rain.attrs['model']+'] '+'.gif',writer='pillow')

    if(output_dir == None):
        #animation.save('rain.gif', fps=75, writer='imagemagick')
        plt.show()
Beispiel #6
0
def draw_Crosssection_Wind_Temp_RH(cross_rh=None,
                                   cross_Temp=None,
                                   cross_u=None,
                                   cross_v=None,
                                   cross_terrain=None,
                                   gh=None,
                                   h_pos=None,
                                   st_point=None,
                                   ed_point=None,
                                   levels=None,
                                   map_extent=(50, 150, 0, 65),
                                   model=None,
                                   output_dir=None):

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

    initial_time = pd.to_datetime(
        str(cross_Temp['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(hours=gh['forecast_period'].values[0])

    fig = plt.figure(1, figsize=(16., 9.))
    ax = plt.axes()
    cross_rh['data'].values[cross_rh['data'].values > 100] = 100

    # example 2: use the "fromList() method
    startcolor = '#1E90FF'  #蓝色
    midcolor = '#F1F1F1'  #白色
    endcolor = '#696969'  #灰色
    cmap2 = col.LinearSegmentedColormap.from_list(
        'own2', [startcolor, midcolor, endcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)

    # we can skip name here as it was already defined

    rh_contour = ax.contourf(cross_rh['lon'],
                             cross_rh['level'],
                             cross_rh['data'],
                             levels=np.arange(0, 101, 0.5),
                             cmap=cm.get_cmap('own2'))
    rh_colorbar = fig.colorbar(rh_contour, ticks=[20, 40, 60, 80, 100])

    # Plot potential temperature using contour, with some custom labeling
    Temp_contour = ax.contour(cross_Temp['lon'],
                              cross_Temp['level'],
                              cross_Temp['data'].values,
                              levels=np.arange(-100, 100, 2),
                              colors='#A0522D',
                              linewidths=1)

    Temp_contour.clabel(np.arange(-100, 100, 2),
                        fontsize=16,
                        colors='#A0522D',
                        inline=1,
                        inline_spacing=8,
                        fmt='%i',
                        rightside_up=True,
                        use_clabeltext=True)

    Temp_zero_contour = ax.contour(cross_Temp['lon'],
                                   cross_Temp['level'],
                                   cross_Temp['data'].values,
                                   levels=[0],
                                   colors='k',
                                   linewidths=3)

    Temp_zero_contour.clabel([0],
                             fontsize=22,
                             colors='k',
                             inline=1,
                             inline_spacing=8,
                             fmt='%i',
                             rightside_up=True,
                             use_clabeltext=True)

    wind_slc_vert = list(range(0, len(levels), 1))
    wind_slc_horz = slice(5, 100, 5)
    ax.barbs(cross_u['lon'][wind_slc_horz],
             cross_u['level'][wind_slc_vert],
             cross_u['t_wind'][wind_slc_vert, wind_slc_horz] * 2.5,
             cross_v['n_wind'][wind_slc_vert, wind_slc_horz] * 2.5,
             color='k')

    startcolor = '#8B4513'  #棕色
    endcolor = '#DAC2AD'  #绿
    cmap2 = col.LinearSegmentedColormap.from_list('own3',
                                                  [endcolor, startcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)
    terrain_contour = ax.contourf(cross_terrain['lon'],
                                  cross_terrain['level'],
                                  cross_terrain.values,
                                  levels=np.arange(0, 200, 1),
                                  cmap=cm.get_cmap('own3'),
                                  zorder=100)
    # Adjust the y-axis to be logarithmic
    ax.set_yscale('symlog')
    ax.set_yticklabels(np.arange(levels[0], levels[-1], -100))
    ax.set_ylim(levels[0], levels[-1])
    ax.set_yticks(np.arange(levels[0], levels[-1], -100))

    # Define the CRS and inset axes
    data_crs = ccrs.PlateCarree()
    ax_inset = fig.add_axes(h_pos, projection=data_crs)
    ax_inset.set_extent(map_extent, crs=data_crs)
    # Plot geopotential height at 500 hPa using xarray's contour wrapper
    ax_inset.contour(gh['lon'],
                     gh['lat'],
                     np.squeeze(gh['data']),
                     levels=np.arange(500, 600, 4),
                     cmap='inferno')
    # Plot the path of the cross section
    endpoints = data_crs.transform_points(
        ccrs.Geodetic(),
        *np.vstack([st_point, ed_point]).transpose()[::-1])
    ax_inset.scatter(endpoints[:, 0], endpoints[:, 1], c='k', zorder=2)
    ax_inset.plot(cross_u['lon'], cross_u['lat'], c='k', zorder=2)
    # Add geographic features
    ax_inset.coastlines()
    utl.add_china_map_2cartopy_public(ax_inset,
                                      name='province',
                                      edgecolor='black',
                                      lw=0.8,
                                      zorder=105)
    # Set the titles and axes labels
    ax_inset.set_title('')

    ax.set_title('[' + model + '] ' + '温度, 相对湿度, 水平风场',
                 loc='right',
                 fontsize=25)
    ax.set_ylabel('Pressure (hPa)')
    ax.set_xlabel('Longitude')
    rh_colorbar.set_label('Relative Humidity (%)')

    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')
    bax = fig.add_axes([0.10, 0.88, .25, .07], facecolor='#FFFFFFCC')
    bax.axis('off')
    #bax.set_yticks([])
    #bax.set_xticks([])
    bax.axis([0, 10, 0, 10])
    plt.text(2.5,
             7.5,
             '起报时间: ' + initial_time.strftime("%Y年%m月%d日%H时"),
             size=11)
    plt.text(2.5, 5, '预报时间: ' + fcst_time.strftime("%Y年%m月%d日%H时"), size=11)
    plt.text(2.5,
             2.5,
             '预报时效: ' + str(int(gh['forecast_period'].values[0])) + '小时',
             size=11)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=11)

    utl.add_logo_extra_in_axes(pos=[0.1, 0.88, .07, .07],
                               which='nmc',
                               size='Xlarge')

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

    if (output_dir == None):
        plt.show()
Beispiel #7
0
def draw_gh_uv_mslp(gh=None,
                    uv=None,
                    mslp=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'].values[0])) + 'hPa 位势高度场, ' +
              str(int(uv['level'].values[0])) + '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 mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs_mslp = np.arange(960, 1065, 5)
        cmap = guide_cmaps(26)
        plots['mslp'] = ax.contourf(x,
                                    y,
                                    np.squeeze(mslp['data']),
                                    clevs_mslp,
                                    cmap=cmap,
                                    alpha=0.8,
                                    zorder=1,
                                    transform=datacrs)
        #+画高低压中心
        res = mslp['lon'].values[1] - mslp['lon'].values[0]
        nwindow = int(9.5 / res)
        mslp_hl = np.ma.masked_invalid(mslp['data'].values).squeeze()
        local_min, local_max = utl.extrema(mslp_hl,
                                           mode='wrap',
                                           window=nwindow)
        #Get location of extrema on grid
        xmin, xmax, ymin, ymax = map_extent2
        lons2d, lats2d = x, y
        transformed = datacrs.transform_points(datacrs, lons2d, lats2d)
        x = transformed[..., 0]
        y = transformed[..., 1]
        xlows = x[local_min]
        xhighs = x[local_max]
        ylows = y[local_min]
        yhighs = y[local_max]
        lowvals = mslp_hl[local_min]
        highvals = mslp_hl[local_max]
        yoffset = 0.022 * (ymax - ymin)
        dmin = yoffset
        #Plot low pressures
        xyplotted = []
        for x, y, p in zip(xlows, ylows, lowvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:  #,fontweight='bold'
                    a = ax.text(x,
                                y,
                                'L',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))

        #Plot high pressures
        xyplotted = []
        for x, y, p in zip(xhighs, yhighs, highvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:
                    a = ax.text(x,
                                y,
                                'H',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))
        #-画高低压中心

    # 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))
        linewidths_gh = np.zeros(clevs_gh.shape) + 2
        idx_588 = np.where(clevs_gh == 588)
        linewidths_gh[idx_588[0]] = 4
        plots['gh'] = ax.contour(x,
                                 y,
                                 np.squeeze(gh['data']),
                                 clevs_gh,
                                 colors='purple',
                                 linewidths=linewidths_gh,
                                 transform=datacrs,
                                 zorder=3)
        ax.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')
    #forecast information
    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])

    initTime = pd.to_datetime(str(
        gh.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=gh.coords['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.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    cax = plt.axes([l, b - 0.04, w, .02])
    cb = plt.colorbar(plots['mslp'],
                      cax=cax,
                      orientation='horizontal',
                      ticks=clevs_mslp[:-1],
                      extend='max',
                      extendrect=False)
    cb.ax.tick_params(labelsize='x-large')
    cb.set_label('Mean sea level pressure (hPa)', 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=6,
                            size=15,
                            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.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')

    if (output_dir == None):
        plt.show()
Beispiel #8
0
def draw_sta_skewT(p=None,
                   T=None,
                   Td=None,
                   wind_speed=None,
                   wind_dir=None,
                   u=None,
                   v=None,
                   fcst_info=None,
                   output_dir=None):
    fig = plt.figure(figsize=(9, 9))
    skew = SkewT(fig, rotation=45)

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

    # Plot the data using normal plotting functions, in this case using
    # log scaling in Y, as dictated by the typical meteorological plot.
    skew.plot(p, T, 'r')
    skew.plot(p, Td, 'g')
    skew.plot_barbs(p, u, v)
    skew.ax.set_ylim(1000, 100)
    skew.ax.set_xlim(-40, 60)

    # Calculate LCL height and plot as black dot. Because `p`'s first value is
    # ~1000 mb and its last value is ~250 mb, the `0` index is selected for
    # `p`, `T`, and `Td` to lift the parcel from the surface. If `p` was inverted,
    # i.e. start from low value, 250 mb, to a high value, 1000 mb, the `-1` index
    # should be selected.
    lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0])
    skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black')

    # Calculate full parcel profile and add to plot as black line
    prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC')
    skew.plot(p, prof, 'k', linewidth=2)

    # Shade areas of CAPE and CIN
    skew.shade_cin(p, T, prof)
    skew.shade_cape(p, T, prof)

    # An example of a slanted line at constant T -- in this case the 0
    # isotherm
    skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)

    # Add the relevant special lines
    skew.plot_dry_adiabats()
    skew.plot_moist_adiabats()
    skew.plot_mixing_lines()

    #forecast information
    bax = plt.axes([0.12, 0.88, .25, .07], facecolor='#FFFFFFCC')
    bax.axis('off')
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(str(
        fcst_info['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    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=11)
    plt.text(2.5,
             5.0,
             '[' + str(fcst_info.attrs['model']) + '] ' +
             str(int(fcst_info['forecast_period'].values[0])) + '小时预报探空',
             size=11)
    plt.text(2.5,
             2.5,
             '预报点: ' + str(fcst_info.attrs['points']['lon']) + ', ' +
             str(fcst_info.attrs['points']['lat']),
             size=11)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=11)
    utl.add_logo_extra_in_axes(pos=[0.1, 0.88, .07, .07],
                               which='nmc',
                               size='Xlarge')

    # Show the plot
    if (output_dir != None):
        plt.savefig(
            output_dir + '时间剖面产品_起报时间_' +
            str(fcst_info['forecast_reference_time'].values)[0:13] + '_预报时效_' +
            str(int(fcst_info.attrs['forecast_period'].values)) + '.png',
            dpi=200,
            bbox_inches='tight')
    else:
        plt.show()
Beispiel #9
0
def draw_point_wind(U=None,
                    V=None,
                    model=None,
                    output_dir=None,
                    points=None,
                    time_info=None,
                    extra_info=None):

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

    initTime = pd.to_datetime(str(
        time_info['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()

    # draw figure
    fig = plt.figure(figsize=(12, 12))
    # draw main figure
    #10米风——————————————————————————————————————
    ax = plt.axes([0.1, 0.2, .8, .7])
    utl.add_public_title_sta(title=model + '预报 ' + extra_info['point_name'] +
                             ' [' + str(points['lon'][0]) + ',' +
                             str(points['lat'][0]) + ']',
                             initTime=initTime,
                             fontsize=21)
    for ifhour in time_info['forecast_period'].values:
        if (ifhour == time_info['forecast_period'].values[0]):
            uv_t = (initTime + timedelta(hours=ifhour))
        else:
            uv_t = np.append(uv_t, (initTime + timedelta(hours=ifhour)))

    wsp = (U**2 + V**2)**0.5
    ax.plot(uv_t, np.squeeze(wsp), c='#40C4FF', linewidth=3)
    if (extra_info['drw_thr'] == True):
        ax.plot([uv_t[0], uv_t[-1]], [11, 11],
                c='red',
                label='警戒风速',
                linewidth=1)

    ax.barbs(uv_t,
             wsp,
             U,
             V,
             fill_empty=True,
             color='gray',
             barb_increments={
                 'half': 2,
                 'full': 4,
                 'flag': 20
             })

    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax.xaxis.set_major_locator(xaxis_intaval)
    plt.xlim(uv_t[0], uv_t[-1])
    # add legend
    ax.legend(fontsize=15, loc='upper right')
    ax.tick_params(length=10)
    xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
    for label in ax.get_xticklabels():
        label.set_rotation(30)
        label.set_horizontalalignment('center')
    ax.tick_params(axis='y', labelsize=15)
    ax.tick_params(axis='x', labelsize=15)

    ax.grid()
    ax.grid(axis='x', c='black')
    miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    ax.grid(axis='x', which='minor')
    ax.set_ylabel('风速 (m/s)', fontsize=15)

    utl.add_logo_extra_in_axes(pos=[0.1, 0.8, .1, .1],
                               which='nmc',
                               size='Xlarge')

    #出图——————————————————————————————————————————————————————————
    if (output_dir != None):
        isExists = os.path.exists(output_dir)
        if not isExists:
            os.makedirs(output_dir)

        output_dir2 = output_dir + model + '_起报时间_' + initTime.strftime(
            "%Y年%m月%d日%H时") + '/'
        if (os.path.exists(output_dir2) == False):
            os.makedirs(output_dir2)

        plt.savefig(output_dir2 + model + '_' + extra_info['point_name'] +
                    '_' + extra_info['output_head_name'] +
                    initTime.strftime("%Y%m%d%H") + '00' +
                    extra_info['output_tail_name'] + '.jpg',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
Beispiel #10
0
def draw_point_fcst(t2m=None,
                    u10m=None,
                    v10m=None,
                    rn=None,
                    model=None,
                    output_dir=None,
                    points=None,
                    extra_info=None):

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

    initTime = pd.to_datetime(str(
        t2m['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()

    # draw figure
    fig = plt.figure(figsize=(16, 4.5))
    ax_t2m = HostAxes(fig, [0.1, 0.28, .8, .62])
    ax_rn = ParasiteAxes(ax_t2m, sharex=ax_t2m)
    #其他信息

    #append axes
    ax_t2m.parasites.append(ax_rn)

    #invisible right axis of ax
    ax_t2m.axis['right'].set_visible(False)
    ax_t2m.axis['right'].set_visible(False)
    ax_rn.axis['right'].set_visible(True)
    ax_rn.axis['right'].major_ticklabels.set_visible(True)
    ax_rn.axis['right'].label.set_visible(True)
    #set label for axis
    ax_t2m.set_ylabel('温度($^\circ$C)', fontsize=100)
    ax_rn.set_ylabel('降水(mm)', fontsize=100)
    fig.add_axes(ax_t2m)

    # draw main figure
    #2米温度——————————————————————————————————————
    if (model == '中央台指导'):
        model = '智能网格'
    utl.add_public_title_sta(title=model + '预报 ' + extra_info['point_name'] +
                             ' [' + str(points['lon'][0]) + ',' +
                             str(points['lat'][0]) + ']',
                             initTime=initTime,
                             fontsize=21)
    for ifhour in t2m['forecast_period'].values:
        if (ifhour == t2m['forecast_period'].values[0]):
            t2m_t = (initTime + timedelta(hours=ifhour))
        else:
            t2m_t = np.append(t2m_t, (initTime + timedelta(hours=ifhour)))

    curve_t2m = ax_t2m.plot(t2m_t,
                            np.squeeze(t2m['data'].values),
                            c='#FF6600',
                            linewidth=3,
                            label='2m温度')
    ax_t2m.set_xlim(t2m_t[0], t2m_t[-1])
    ax_t2m.set_ylim(
        math.floor(t2m['data'].values.min() / 5) * 5 - 2,
        math.ceil(t2m['data'].values.max() / 5) * 5)
    #降水——————————————————————————————————————
    for ifhour in rn['forecast_period'].values:
        if (ifhour == rn['forecast_period'].values[0]):
            rn_t = (initTime + timedelta(hours=ifhour))
        else:
            rn_t = np.append(rn_t, (initTime + timedelta(hours=ifhour)))
    mask = (rn['data'] < 999)
    rn = rn['data'].where(mask)
    ax_rn.bar(rn_t,
              np.squeeze(rn.values),
              width=0.1,
              color='#00008B',
              label=str(
                  int(rn['forecast_period'].values[1] -
                      rn['forecast_period'].values[0])) + '小时降水',
              alpha=0.5)
    #curve_rn=ax_rn.plot(rn_t, np.squeeze(rn['data'].values), c='#40C4FF',linewidth=3)

    ax_rn.set_ylim(0, np.nanmax(np.append(10, np.squeeze(rn.values))))
    ###

    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax_t2m.xaxis.set_major_locator(xaxis_intaval)
    # add legend
    ax_t2m.legend(fontsize=15, loc='upper right')
    ax_t2m.tick_params(length=10)
    ax_t2m.tick_params(axis='y', labelsize=100)
    ax_t2m.set_xticklabels([' '])
    miloc = mpl.dates.HourLocator(byhour=(8, 11, 14, 17, 20, 23, 2, 5))  #单位是小时
    ax_t2m.xaxis.set_minor_locator(miloc)
    yminorLocator = MultipleLocator(1)  #将此y轴次刻度标签设置为1的倍数
    ax_t2m.yaxis.set_minor_locator(yminorLocator)
    ymajorLocator = MultipleLocator(5)  #将此y轴次刻度标签设置为1的倍数
    ax_t2m.yaxis.set_major_locator(ymajorLocator)

    ax_t2m.grid(axis='x', which='minor', ls='--')
    ax_t2m.axis['left'].label.set_fontsize(15)
    ax_t2m.axis['left'].major_ticklabels.set_fontsize(15)
    ax_rn.axis['right'].label.set_fontsize(15)
    ax_rn.axis['right'].major_ticklabels.set_fontsize(15)
    #10米风——————————————————————————————————————
    ax_uv = plt.axes([0.1, 0.16, .8, .12])
    for ifhour in u10m['forecast_period'].values:
        if (ifhour == u10m['forecast_period'].values[0]):
            uv_t = (initTime + timedelta(hours=ifhour))
        else:
            uv_t = np.append(uv_t, (initTime + timedelta(hours=ifhour)))

    wsp = (u10m**2 + v10m**2)**0.5
    #curve_uv=ax_uv.plot(uv_t, np.squeeze(wsp['data'].values), c='#696969',linewidth=3,label='10m风')

    ax_uv.barbs(uv_t,
                np.zeros(len(uv_t)),
                np.squeeze(u10m['data'].values),
                np.squeeze(v10m['data'].values),
                fill_empty=True,
                color='gray',
                barb_increments={
                    'half': 2,
                    'full': 4,
                    'flag': 20
                },
                length=5.8,
                linewidth=1.5,
                zorder=100)
    ax_uv.set_ylim(-1, 1)
    ax_uv.set_xlim(uv_t[0], uv_t[-1])
    #ax_uv.axis('off')
    ax_uv.set_yticklabels([' '])
    #logo
    utl.add_logo_extra_in_axes(pos=[0.87, 0.00, .1, .1],
                               which='nmc',
                               size='Xlarge')

    #开启自适应
    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax_uv.xaxis.set_major_locator(xaxis_intaval)
    ax_uv.tick_params(length=5, axis='x')
    ax_uv.tick_params(length=0, axis='y')
    miloc = mpl.dates.HourLocator(byhour=(8, 11, 14, 17, 20, 23, 2, 5))  #单位是小时
    ax_uv.xaxis.set_minor_locator(miloc)
    ax_uv.grid(axis='x', which='both', ls='--')
    ax_uv.set_ylabel('10m风', fontsize=15)

    xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
    for label in ax_uv.get_xticklabels():
        label.set_rotation(30)
        label.set_horizontalalignment('center')
    ax_uv.tick_params(axis='x', labelsize=15)

    #出图——————————————————————————————————————————————————————————

    if (output_dir != None):
        isExists = os.path.exists(output_dir)
        if not isExists:
            os.makedirs(output_dir)

        output_dir2 = output_dir + model + '_起报时间_' + initTime.strftime(
            "%Y年%m月%d日%H时") + '/'
        if (os.path.exists(output_dir2) == False):
            os.makedirs(output_dir2)

        plt.savefig(output_dir2 + model + '_' + extra_info['point_name'] +
                    '_' + extra_info['output_head_name'] +
                    initTime.strftime("%Y%m%d%H") + '00' +
                    extra_info['output_tail_name'] + '.jpg',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
Beispiel #11
0
def draw_Station_Snow_Synthetical_Forecast_From_Cassandra(
    TWC=None,
    AT=None,
    u10m=None,
    v10m=None,
    u100m=None,
    v100m=None,
    gust10m=None,
    wsp10m=None,
    wsp100m=None,
    SNOD1=None,
    SNOD2=None,
    SDEN=None,
    SN06=None,
    draw_VIS=False,
    VIS=None,
    drw_thr=False,
    time_all=None,
    model=None,
    points=None,
    output_dir=None,
    extra_info={
        'output_head_name': ' ',
        'output_tail_name': ' ',
        'point_name': ' '
    }):

    #if(sys.platform[0:3] == 'win'):
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)
    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')

    initTime1 = pd.to_datetime(str(
        TWC['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    initTime2 = pd.to_datetime(str(
        VIS['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()

    # draw figure
    fig = plt.figure(figsize=(12, 16))
    # draw main figure
    #风寒指数 体感温度————————————————————————————————————————————————
    ax = plt.axes([0.05, 0.83, .94, .15])
    utl.add_public_title_sta(title=model + '预报 ' + extra_info['point_name'] +
                             ' [' + str(points['lon'][0]) + ',' +
                             str(points['lat'][0]) + ']',
                             initTime=initTime1,
                             fontsize=23)

    for ifhour in TWC['forecast_period'].values:
        if (ifhour == TWC['forecast_period'].values[0]):
            TWC_t = (initTime1 + timedelta(hours=ifhour))
        else:
            TWC_t = np.append(TWC_t, (initTime1 + timedelta(hours=ifhour)))
    #开启自适应
    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax.xaxis.set_major_locator(xaxis_intaval)
    ax.set_xticklabels([' '])
    ax.plot(TWC_t, np.squeeze(TWC), label='风寒指数')
    ax.plot(TWC_t, np.squeeze(AT), c='#00796B', label='2米体感温度')
    ax.tick_params(length=10)
    ax.grid()
    ax.grid(axis='x', c='black')
    miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    ax.grid(axis='x', which='minor')
    plt.xlim(time_all[0], time_all[-1])
    plt.ylim(min([AT.values.min(), TWC.values.min()]),
             max([AT.values.max(), TWC.values.max()]))
    ax.legend(fontsize=10, loc='upper right')
    ax.set_ylabel('2米体感温度 风寒指数 ($^\circ$C)', fontsize=15)

    #10米风——————————————————————————————————————
    ax = plt.axes([0.05, 0.66, .94, .15])
    for ifhour in u10m['forecast_period'].values:
        if (ifhour == u10m['forecast_period'].values[0]):
            uv10m_t = (initTime1 + timedelta(hours=ifhour))
        else:
            uv10m_t = np.append(uv10m_t, (initTime1 + timedelta(hours=ifhour)))

    for ifhour in u100m['forecast_period'].values:
        if (ifhour == u100m['forecast_period'].values[0]):
            uv100m_t = (initTime1 + timedelta(hours=ifhour))
        else:
            uv100m_t = np.append(uv100m_t,
                                 (initTime1 + timedelta(hours=ifhour)))

    for ifhour in gust10m['forecast_period'].values:
        if (ifhour == gust10m['forecast_period'].values[0]):
            gust10m_t = (initTime1 + timedelta(hours=ifhour))
        else:
            gust10m_t = np.append(gust10m_t,
                                  (initTime1 + timedelta(hours=ifhour)))

    ax.plot(uv10m_t,
            np.squeeze(wsp10m),
            c='#40C4FF',
            label='10米风',
            linewidth=3)
    ax.plot(uv100m_t,
            np.squeeze(wsp100m),
            c='#FF6F00',
            label='100米风',
            linewidth=3)
    ax.plot(gust10m_t,
            np.squeeze(gust10m['data']),
            c='#7C4DFF',
            label='10米阵风',
            linewidth=3)
    if (drw_thr == True):
        ax.plot([uv10m_t[0], uv10m_t[-1]], [5.5, 5.5],
                c='#4CAE50',
                label='10米平均风一般影响',
                linewidth=1)
        ax.plot([uv10m_t[0], uv10m_t[-1]], [8, 8],
                c='#FFEB3B',
                label='10米平均风较大影响',
                linewidth=1)
        ax.plot([uv10m_t[0], uv10m_t[-1]], [10.8, 10.8],
                c='#F44336',
                label='10米平均风高影响',
                linewidth=1)

        ax.plot([gust10m_t[0], gust10m_t[-1]], [10.8, 10.8],
                c='#4CAE50',
                label='10米阵风一般影响',
                dashes=[6, 2],
                linewidth=1)
        ax.plot([gust10m_t[0], gust10m_t[-1]], [13.9, 13.9],
                c='#FFEB3B',
                label='10米阵风较大影响',
                dashes=[6, 2],
                linewidth=1)
        ax.plot([gust10m_t[0], gust10m_t[-1]], [17.2, 17.2],
                c='#F44336',
                label='10米阵风高影响',
                dashes=[6, 2],
                linewidth=1)

    ax.barbs(uv10m_t[0:-1],
             wsp10m[0:-1],
             np.squeeze(u10m['data'])[0:-1],
             np.squeeze(v10m['data'])[0:-1],
             fill_empty=True,
             color='gray',
             barb_increments={
                 'half': 2,
                 'full': 4,
                 'flag': 20
             })

    ax.barbs(uv100m_t[0:-1],
             wsp100m[0:-1],
             np.squeeze(u100m['data'])[0:-1],
             np.squeeze(v100m['data'])[0:-1],
             fill_empty=True,
             color='gray',
             barb_increments={
                 'half': 2,
                 'full': 4,
                 'flag': 20
             })

    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax.xaxis.set_major_locator(xaxis_intaval)
    ax.set_xticklabels([' '])
    plt.xlim(time_all[0], time_all[-1])
    # add legend
    ax.legend(fontsize=10, loc='upper right')
    ax.tick_params(length=10)
    ax.grid()
    ax.grid(axis='x', c='black')
    miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    ax.grid(axis='x', which='minor')
    ax.set_ylabel('10米风 100米 风\n' + '风速 (m/s)', fontsize=15)
    #雪密度——————————————————————————————————————
    # draw main figure
    ax = plt.axes([0.05, 0.49, .94, .15])
    for ifhour in SDEN['forecast_period'].values:
        if (ifhour == SDEN['forecast_period'].values[0]):
            SDEN_t = (initTime1 + timedelta(hours=ifhour))
        else:
            SDEN_t = np.append(SDEN_t, (initTime1 + timedelta(hours=ifhour)))
    #开启自适应
    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax.xaxis.set_major_locator(xaxis_intaval)
    ax.set_xticklabels([' '])

    ax.plot(SDEN_t, np.squeeze(SDEN['data']), color='#1E88E5', label='雪密度')
    #ax.bar(SDEN_t,np.squeeze(SDEN['data']),width=0.12,color='#1E88E5')
    gap_hour_SDEN = int(SDEN['forecast_period'].values[1] -
                        SDEN['forecast_period'].values[0])

    if (drw_thr == True):
        ax.plot([SDEN_t[0], SDEN_t[-1]],
                [1 * gap_hour_SDEN, 1 * gap_hour_SDEN],
                c='#FFEB3B',
                label=str(gap_hour_SDEN) + '小时降水较大影响',
                linewidth=1)
        ax.plot([SDEN_t[0], SDEN_t[-1]],
                [10 * gap_hour_SDEN, 10 * gap_hour_SDEN],
                c='#F44336',
                label=str(gap_hour_SDEN) + '小时降水高影响',
                linewidth=1)
        ax.legend(fontsize=10, loc='upper right')
    ax.tick_params(length=10)
    ax.grid()
    ax.grid(axis='x', c='black')
    miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    ax.grid(axis='x', which='minor')
    plt.xlim(time_all[0], time_all[-1])
    plt.ylim([
        np.squeeze(SDEN['data']).values.min(),
        np.squeeze(SDEN['data'].values.max()) + 2
    ])
    ax.set_ylabel('雪密度 (kg m-3)', fontsize=15)
    #积雪深度——————————————————————————————————————
    # draw main figure
    ax = plt.axes([0.05, 0.32, .94, .15])
    for ifhour in SNOD1['forecast_period'].values:
        if (ifhour == SNOD1['forecast_period'].values[0]):
            SNOD1_t = (initTime1 + timedelta(hours=ifhour))
        else:
            SNOD1_t = np.append(SNOD1_t, (initTime1 + timedelta(hours=ifhour)))
    # draw main figure
    for ifhour in SNOD2['forecast_period'].values:
        if (ifhour == SNOD2['forecast_period'].values[0]):
            SNOD2_t = (initTime1 + timedelta(hours=ifhour))
        else:
            SNOD2_t = np.append(SNOD2_t, (initTime1 + timedelta(hours=ifhour)))

    for ifhour in SN06['forecast_period'].values:
        if (ifhour == SN06['forecast_period'].values[0]):
            SN06_t = (initTime1 + timedelta(hours=ifhour))
        else:
            SN06_t = np.append(SN06_t, (initTime1 + timedelta(hours=ifhour)))
    #开启自适应
    xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
    ax.xaxis.set_major_locator(xaxis_intaval)
    ax.set_xticklabels([' '])

    #ax.bar(SNOD1_t,np.squeeze(SNOD1['data']),width=0.20,color='#82B1FF',label='EC预报积雪深度')
    #ax.bar(SNOD2_t,np.squeeze(SNOD2['data']),width=0.125,color='#2962FF',label='NCEP预报积雪深度')
    ax.plot(SNOD1_t,
            np.squeeze(SNOD1['data']),
            dashes=[6, 2],
            color='#4B4B4B',
            linewidth=3,
            label='EC预报积雪深度')
    ax.plot(SNOD2_t,
            np.squeeze(SNOD2['data']),
            dashes=[6, 2],
            color='#969696',
            linewidth=3,
            label='NCEP预报积雪深度')
    ax.plot(SN06_t,
            np.squeeze(SN06['data']),
            color='#82B1FF',
            linewidth=2,
            label='EC预报降雪量')

    ax.tick_params(length=10)
    ax.grid()
    ax.grid(axis='x', c='black')
    miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    ax.grid(axis='x', which='minor')
    plt.xlim(time_all[0], time_all[-1])
    plt.ylim(0, 100)
    ax.legend(fontsize=10, loc='upper right')
    plt.ylim(
        min([
            np.squeeze(SNOD1['data']).values.min(),
            np.squeeze(SNOD2['data']).values.min()
        ]),
        max([
            np.squeeze(SNOD1['data']).values.max(),
            np.squeeze(SNOD2['data']).values.max()
        ]) + 5)
    ax.set_ylabel('积雪深度 (cm)\n' + '6小时降雪量(mm)', fontsize=15)

    if (draw_VIS == False):
        xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
        ax.xaxis.set_major_formatter(xstklbls)
        for label in ax.get_xticklabels():
            label.set_rotation(30)
            label.set_horizontalalignment('center')

        #发布信息————————————————————————————————————————————————
        ax = plt.axes([0.05, 0.08, .94, .05])
        ax.axis([0, 10, 0, 10])
        ax.axis('off')
        utl.add_logo_extra_in_axes(pos=[0.7, 0.23, .05, .05],
                                   which='nmc',
                                   size='Xlarge')
        ax.text(7.5,
                33, (initTime1 - timedelta(hours=2)).strftime("%Y年%m月%d日%H时") +
                '发布',
                size=15)

    if (draw_VIS == True):
        #能见度——————————————————————————————————————
        # draw main figure
        ax = plt.axes([0.05, 0.15, .94, .15])

        #VIS=pd.read_csv(dir_all['VIS_SC']+last_file[model])
        for ifhour in VIS['forecast_period'].values:
            if (ifhour == VIS['forecast_period'].values[0]):
                VIS_t = (initTime2 + timedelta(hours=ifhour))
            else:
                VIS_t = np.append(VIS_t, (initTime2 + timedelta(hours=ifhour)))

        #开启自适应
        xaxis_intaval = mpl.dates.HourLocator(byhour=(8, 20))  #单位是小时
        ax.xaxis.set_major_locator(xaxis_intaval)

        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        -100,
                        facecolor='#B3E5FC')
        ax.fill_between(VIS_t, np.squeeze(VIS['data']), 1, facecolor='#81D4FA')
        ax.fill_between(VIS_t, np.squeeze(VIS['data']), 3, facecolor='#4FC3F7')
        ax.fill_between(VIS_t, np.squeeze(VIS['data']), 5, facecolor='#29B6F6')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        10,
                        facecolor='#03A9F4')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        15,
                        facecolor='#039BE5')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        20,
                        facecolor='#0288D1')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        25,
                        facecolor='#0277BD')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        30,
                        facecolor='#01579B')
        ax.fill_between(VIS_t,
                        np.squeeze(VIS['data']),
                        100,
                        facecolor='#FFFFFF')

        ax.plot(VIS_t, np.squeeze(VIS['data']))
        if (drw_thr == True):
            ax.plot([VIS_t[0], VIS_t[-1]], [5, 5],
                    c='#4CAF50',
                    label='能见度一般影响',
                    linewidth=1)
            ax.plot([VIS_t[0], VIS_t[-1]], [3, 3],
                    c='#FFEB3B',
                    label='能见度较大影响',
                    linewidth=1)
            ax.plot([VIS_t[0], VIS_t[-1]], [1, 1],
                    c='#F44336',
                    label='能见度高影响',
                    linewidth=1)
            ax.legend(fontsize=10, loc='upper right')

        xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
        ax.xaxis.set_major_formatter(xstklbls)
        for label in ax.get_xticklabels():
            label.set_rotation(30)
            label.set_horizontalalignment('center')
        ax.tick_params(length=10)
        ax.grid()
        ax.grid(axis='x', c='black')
        miloc = mpl.dates.HourLocator(byhour=(11, 14, 17, 23, 2, 5))  #单位是小时
        ax.xaxis.set_minor_locator(miloc)
        ax.grid(axis='x', which='minor')
        plt.xlim(time_all[0], time_all[-1])
        plt.ylim(0, 25)
        ax.set_ylabel('能见度 (km)', fontsize=15)
        #发布信息————————————————————————————————————————————————
        ax = plt.axes([0.05, 0.08, .94, .05])
        ax.axis([0, 10, 0, 10])
        ax.axis('off')
        utl.add_logo_extra_in_axes(pos=[0.7, 0.06, .05, .05],
                                   which='nmc',
                                   size='Xlarge')
        ax.text(7.5,
                0.1,
                (initTime2 - timedelta(hours=2)).strftime("%Y年%m月%d日%H时") +
                '发布',
                size=15)

    #出图——————————————————————————————————————————————————————————
    if (output_dir != None):
        isExists = os.path.exists(output_dir)
        if not isExists:
            os.makedirs(output_dir)
        plt.savefig(output_dir + extra_info['output_head_name'] +
                    initTime1.strftime("%Y%m%d%H") + '00' +
                    extra_info['output_tail_name'] + '.jpg',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
Beispiel #12
0
def draw_mslp_rain_snow(
        rain=None, snow=None,sleet=None,mslp=None,
        map_extent=(50, 150, 0, 65),
        regrid_shape=20,
        add_china=True,city=True,south_China_sea=True,
        output_dir=None,Global=False):
# set font
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

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

    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)
    
    datacrs = ccrs.PlateCarree()
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    plt.title('['+mslp.attrs['model']+'] '+
    '海平面气压, '+
    str(rain.attrs['atime'])+'小时降水', 
        loc='left', fontsize=30)

#draw data
    plots = {}
    if rain is not None:
        x, y = np.meshgrid(rain['lon'], rain['lat'])
        z=np.squeeze(rain.values)
        cmap,norm=dk_ctables.cm_rain_nws(atime=rain.attrs['atime'])
        #cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['rain'] = ax.pcolormesh(
            x,y,z, norm=norm,
            cmap=cmap, zorder=3,transform=datacrs,alpha=0.8)

    if snow is not None:
        x, y = np.meshgrid(snow['lon'], snow['lat'])
        z=np.squeeze(snow.values)
        cmap,norm=dk_ctables.cm_snow_nws(atime=rain.attrs['atime'])
        #cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['snow'] = ax.pcolormesh(
            x,y,z, norm=norm,
            cmap=cmap, zorder=3,transform=datacrs,alpha=0.8)
    
    if sleet is not None:
        x, y = np.meshgrid(sleet['lon'], sleet['lat'])
        z=np.squeeze(sleet.values)
        cmap,norm=dk_ctables.cm_sleet_nws(atime=rain.attrs['atime'])
        #cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['sleet'] = ax.pcolormesh(
            x,y,z, norm=norm,
            cmap=cmap, zorder=3,transform=datacrs,alpha=0.8)

    if mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs_mslp = np.arange(900, 1100,2.5)
        z=gaussian_filter(np.squeeze(mslp['data']), 5)
        plots['mslp'] = ax.contour(
            x, y, z, clevs_mslp, colors='black',
            linewidths=2, transform=datacrs, zorder=3)
        plt.clabel(plots['mslp'], inline=1, fontsize=20, fmt='%.0f',colors='black')
#additional information
    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(
        ax, name='coastline', edgecolor='gray', lw=0.8, zorder=1,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=1)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=1)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=1,alpha=0.5)

    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=1)
    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')
    ax.add_feature(cfeature.LAND,color='#F5E19F')
    ax.add_feature(cfeature.OCEAN)
    
    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(mslp.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=mslp.coords['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(mslp.coords['forecast_period'].values[0]))+'小时',size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    if(sleet is not None):
        cax=plt.axes([l-0.03,b-0.04,w/3,.02])
        cb = plt.colorbar(plots['sleet'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label('雨夹雪 (mm)',size=20)

    if(snow is not None):
        # cax=plt.axes([l+0.32,b-0.04,w/4,.02])
        cax=plt.axes([l+w/3,b-0.04,w/3,.02])
        cb = plt.colorbar(plots['snow'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label('雪 (mm)',size=20)

    if(rain is not None):
        # cax=plt.axes([l+0.65,b-0.04,w/4,.02])
        cax=plt.axes([l+w*2/3+0.03,b-0.04,w/3,.02])
        cb = plt.colorbar(plots['rain'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label('雨 (mm)',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=110,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(int(mslp.coords['forecast_period'].values[0]))+'小时'+'.png',
         dpi=200,bbox_inches='tight')
        plt.close()
    
    if(output_dir == None):
        plt.show()
Beispiel #13
0
def draw_gh_uv_r6(gh=None, uv=None, r6=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,city=True,south_China_sea=True,
                    output_dir=None,Global=False):
    """
    Draw -hPa geopotential height contours, -hPa wind barbs
    and mean sea level pressure filled contours.
    :param gh: -hPa gh, dictionary:
                  necessary, {'lon': 1D array, 'lat': 1D array,
                              'data': 2D array}
                  optional, {'clevs': 1D array}
    :param uv: -hPa u-component and v-component wind, dictionary:
                  necessary, {'lon': 1D array, 'lat': 1D array,
                              'udata': 2D array, 'vdata': 2D array}
    :param r6: r6, dictionary:
                 necessary, {'lon': 1D array, 'lat': 1D array,
                             'data': 2D array}
                 optional, {'clevs': 1D array}
    :param map_extent: [lonmin, lonmax, latmin, latmax],
                       longitude and latitude range.
    :param add_china: add china map or not.
    :param regrid_shape: control the wind barbs density.
    :return: plots dictionary.

    :Examples:
    """

    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['model']+'] '+
    gh['lev']+'hPa 位势高度场, '+
    uv['lev']+'hPa 风场, 6小时降水', 
        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=105,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=105)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=105)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=105,alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if r6 is not None:
        x, y = np.meshgrid(r6['lon'], r6['lat'])
        clevs_r6 = [0.1, 4, 13, 25, 60, 120]
        plots['r6'] = ax.contourf(
            x, y, np.squeeze(r6['data']), clevs_r6,
            colors=["#88F492", "#00A929", "#2AB8FF", "#1202FC", "#FF04F4", "#850C3E"],
            alpha=0.8, zorder=10, transform=datacrs,extend='max',extendrect=False)

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

    # 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=30)
        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=40)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    #http://earthpy.org/cartopy_backgroung.html
    #C:\ProgramData\Anaconda3\Lib\site-packages\cartopy\data\raster\natural_earth
    ax.background_img(name='RD', resolution='high')

    #forecast information
    bax=plt.axes([0.01,0.835,.25,.1],facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(
    str(gh['init_time'])).replace(tzinfo=None).to_pydatetime()
    fcst_time=initial_time+timedelta(hours=gh['fhour'])
    #发布时间
    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(gh['fhour'])+'小时',size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    if(r6 != None):
        cax=plt.axes([0.11,0.06,.86,.02])
        cb = plt.colorbar(plots['r6'], cax=cax, orientation='horizontal',
                      ticks=clevs_r6[:],
                      extend='max',extendrect=False)
        cb.ax.tick_params(labelsize='x-large')                      
        cb.set_label('6h precipitation (mm)',size=20)

    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[0.85,0.13,.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=110,size=13,small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[-0.01,0.835,.1,.1],which='nmc', size='Xlarge')

    # show figure
    if(output_dir != None):
        plt.savefig(output_dir+'高度场_风场_降水_预报_'+
        '起报时间_'+initial_time.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(gh['fhour'])+'小时'+'.png', dpi=200)
    
    if(output_dir == None):
        plt.show()      
def draw_Time_Crossection_rh_uv_t(
                    rh_2D=None, u_2D=None, v_2D=None,TMP_2D=None,
                    t_range=None,lw_ratio=[16,9],output_dir=None):   

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

    # example 2: use the "fromList() method
    startcolor = '#1E90FF'   #蓝色
    midcolor = '#F1F1F1'     #白色
    endcolor = '#696969'     #灰色
    cmap2 = col.LinearSegmentedColormap.from_list('own2',['#1E90FF','#94D8F6','#F1F1F1','#BFBFBF','#696969'])
    
    rh_contour = ax.contourf(rh_2D['time'].values, rh_2D['level'].values, np.squeeze(rh_2D['data'].values.swapaxes(1,0)),                            
                            levels=np.arange(0, 101, 0.5), cmap=cmap2,extend='max')
    rh_colorbar = fig.colorbar(rh_contour,ticks=[20,40,60,80,100])
    rh_colorbar.set_label('相对湿度(%)',size=15)

    ax.barbs(u_2D['time'].values, u_2D['level'].values,
            np.squeeze(u_2D['data'].values.swapaxes(1,0))*2.5,
            np.squeeze(v_2D['data'].values.swapaxes(1,0))*2.5, color='k')

    TMP_contour = ax.contour(TMP_2D['time'].values, TMP_2D['level'].values,  np.squeeze(TMP_2D['data'].values.swapaxes(1,0)),
                            levels=np.arange(-100, 40, 5), colors='#F4511E', linewidths=2)
    TMP_contour.clabel(TMP_contour.levels[1::2], fontsize=15, colors='#F4511E', inline=1,
                        inline_spacing=8, fmt='%i', rightside_up=True, use_clabeltext=True)

    xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
    ax.xaxis.set_major_formatter(xstklbls)
    for label in ax.get_xticklabels():
        label.set_rotation(30)
        label.set_fontsize(15)
        label.set_horizontalalignment('right')

    for label in ax.get_yticklabels():
        label.set_fontsize(15)
            
    ax.set_yscale('symlog')
    ax.set_ylabel('高度 (hPa)', fontsize=15)
    ax.set_yticklabels(np.arange(1000, 50, -100))
    ax.set_yticks(np.arange(1000, 50, -100))
    ax.set_ylim(rh_2D['level'].values.max(), rh_2D['level'].values.min())
    ax.set_xlim([rh_2D['time'].values[0], rh_2D['time'].values[-1]])

#forecast information
    bax=plt.axes([0.10,0.88,.25,.07],facecolor='#FFFFFFCC')
    bax.axis('off')
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(
        str(rh_2D['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    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=11)
    plt.text(2.5, 5.0,'['+str(rh_2D.attrs['model'])+']'+'模式时间剖面',size=11)
    plt.text(2.5, 2.5,'预报点: '+str(rh_2D.attrs['points']['lon'])+
        ', '+str(rh_2D.attrs['points']['lat']),size=11)
    plt.text(2.5, 0.5,'www.nmc.cn',size=11)
    utl.add_logo_extra_in_axes(pos=[0.1,0.88,.07,.07],which='nmc', size='Xlarge')
    ax.set_title('温度, 相对湿度, 水平风', loc='right', fontsize=23)

    #出图——————————————————————————————————————————————————————————
    if(output_dir != None ):
        plt.savefig(output_dir+'时间剖面产品_起报时间_'+
        str(rh_2D['forecast_reference_time'].values)[0:13]+
        '_预报时效_'+str(t_range[0])+'_至_'+str(t_range[1])
        +'.png', dpi=200,bbox_inches='tight')
        plt.close()
    else:
        plt.show()                                  
Beispiel #15
0
def draw_Crosssection_Wind_Theta_e_Qv(cross_Qv=None,
                                      cross_Theta_e=None,
                                      cross_u=None,
                                      cross_v=None,
                                      gh=None,
                                      h_pos=None,
                                      st_point=None,
                                      ed_point=None,
                                      levels=None,
                                      map_extent=(50, 150, 0, 65),
                                      output_dir=None):

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

    initial_time = pd.to_datetime(
        str(cross_Theta_e['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(hours=gh['forecast_period'].values[0])

    fig = plt.figure(1, figsize=(16., 9.))
    ax = plt.axes()
    Qv_contour = ax.contourf(cross_Qv['lon'],
                             cross_Qv['level'],
                             cross_Qv.values,
                             levels=np.arange(0, 20, 2),
                             cmap='YlGnBu')
    Qv_colorbar = fig.colorbar(Qv_contour)

    # Plot potential temperature using contour, with some custom labeling
    Theta_e_contour = ax.contour(cross_Theta_e['lon'],
                                 cross_Theta_e['level'],
                                 cross_Theta_e.values,
                                 levels=np.arange(250, 450, 5),
                                 colors='k',
                                 linewidths=2)

    Theta_e_contour.clabel(np.arange(250, 450, 5),
                           fontsize=8,
                           colors='k',
                           inline=1,
                           inline_spacing=8,
                           fmt='%i',
                           rightside_up=True,
                           use_clabeltext=True)

    wind_slc_vert = list(range(0, len(levels), 1))
    wind_slc_horz = slice(5, 100, 5)
    ax.barbs(cross_u['lon'][wind_slc_horz],
             cross_u['level'][wind_slc_vert],
             cross_u['t_wind'][wind_slc_vert, wind_slc_horz] * 2.5,
             cross_v['n_wind'][wind_slc_vert, wind_slc_horz] * 2.5,
             color='k')
    # Adjust the y-axis to be logarithmic
    ax.set_yscale('symlog')
    ax.set_yticklabels(np.arange(levels[0], levels[-1], -100))
    ax.set_ylim(levels[0], levels[-1])
    ax.set_yticks(np.arange(levels[0], levels[-1], -100))

    # Define the CRS and inset axes
    data_crs = ccrs.PlateCarree()
    ax_inset = fig.add_axes(h_pos, projection=data_crs)
    ax_inset.set_extent(map_extent, crs=data_crs)
    # Plot geopotential height at 500 hPa using xarray's contour wrapper
    ax_inset.contour(gh['lon'],
                     gh['lat'],
                     np.squeeze(gh['data']),
                     levels=np.arange(500, 600, 4),
                     cmap='inferno')
    # Plot the path of the cross section
    endpoints = data_crs.transform_points(
        ccrs.Geodetic(),
        *np.vstack([st_point, ed_point]).transpose()[::-1])
    ax_inset.scatter(endpoints[:, 0], endpoints[:, 1], c='k', zorder=2)
    ax_inset.plot(cross_u['lon'], cross_u['lat'], c='k', zorder=2)
    # Add geographic features
    ax_inset.coastlines()
    utl.add_china_map_2cartopy_public(ax_inset,
                                      name='province',
                                      edgecolor='black',
                                      lw=0.8,
                                      zorder=105)
    # Set the titles and axes labels
    ax_inset.set_title('')

    ax.set_title('相当位温, 绝对湿度, 水平风场', loc='right', fontsize=25)
    ax.set_ylabel('Pressure (hPa)')
    ax.set_xlabel('Longitude')
    Qv_colorbar.set_label('Specific Humidity (g/kg)')

    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')
    bax = fig.add_axes([0.10, 0.88, .25, .07], facecolor='#FFFFFFCC')
    bax.axis('off')
    #bax.set_yticks([])
    #bax.set_xticks([])
    bax.axis([0, 10, 0, 10])
    plt.text(2.5,
             7.5,
             '起报时间: ' + initial_time.strftime("%Y年%m月%d日%H时"),
             size=11)
    plt.text(2.5, 5, '预报时间: ' + fcst_time.strftime("%Y年%m月%d日%H时"), size=11)
    plt.text(2.5,
             2.5,
             '预报时效: ' + str(int(gh['forecast_period'].values[0])) + '小时',
             size=11)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=11)

    utl.add_logo_extra_in_axes(pos=[0.1, 0.88, .07, .07],
                               which='nmc',
                               size='Xlarge')

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

    if (output_dir == None):
        plt.show()
Beispiel #16
0
def draw_T_2m(T_2m=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('[' + T_2m['model'] + ']' + ' ' + T_2m['title'],
              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=105,
                                      alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(ax,
                                          name='province',
                                          edgecolor='gray',
                                          lw=0.5,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='nation',
                                          edgecolor='black',
                                          lw=0.8,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='river',
                                          edgecolor='#74b9ff',
                                          lw=0.8,
                                          zorder=105,
                                          alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if T_2m is not None:
        x, y = np.meshgrid(T_2m['lon'], T_2m['lat'])
        z = np.squeeze(T_2m['data'])
        cmap = dk_ctables.cm_temperature_nws()
        cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)
        plots['T_2m'] = ax.pcolormesh(x,
                                      y,
                                      z,
                                      cmap=cmap,
                                      zorder=100,
                                      transform=datacrs,
                                      alpha=0.5,
                                      vmin=-45,
                                      vmax=45)

        clevs_zero = 0
        z = gaussian_filter(z, 5)
        plots['T_2m_zero'] = ax.contour(x,
                                        y,
                                        z,
                                        clevs_zero,
                                        colors='red',
                                        linewidths=2,
                                        transform=datacrs,
                                        zorder=110)

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

    #http://earthpy.org/cartopy_backgroung.html
    #C:\ProgramData\Anaconda3\Lib\site-packages\cartopy\data\raster\natural_earth
    ax.background_img(name='RD', resolution='high')

    #forecast information
    bax = plt.axes([0.01, 0.835, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(str(
        T_2m['init_time'])).replace(tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(hours=T_2m['fhour'])
    #发布时间
    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(T_2m['fhour']) + '小时', size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (T_2m != None):
        cax = plt.axes([0.11, 0.06, .86, .02])
        cb = plt.colorbar(plots['T_2m'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label(u'°C', size=20)

    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[0.85, 0.13, .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=110,
                            size=13,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[-0.01, 0.835, .1, .1],
                               which='nmc',
                               size='Xlarge')

    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '最低温度_预报_' + '起报时间_' +
                    initial_time.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(T_2m['fhour']) + '小时' + '.png',
                    dpi=200)
    if (output_dir == None):
        plt.show()
Beispiel #17
0
def draw_Time_Crossection_rh_uv_theta_e(rh_2D=None,
                                        u_2D=None,
                                        v_2D=None,
                                        theta_e_2D=None,
                                        t_range=None,
                                        output_dir=None):

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

    #   utl.add_public_title_sta(title=rh_2D.attrs['model']+'模式预报时间剖面',initial_time=rh_2D['forecast_reference_time'].values, fontsize=23)

    # Plot RH using contourf
    #rh_contour = ax.contourf(rh_2D['time'].values, rh_2D['level'].values, np.squeeze(rh_2D['data'].values.swapaxes(1,0)),
    #                        levels=np.arange(0, 106, 5), cmap='RdBu')
    rh_contour = ax.contourf(rh_2D['time'].values,
                             rh_2D['level'].values,
                             np.squeeze(rh_2D['data'].values.swapaxes(1, 0)),
                             levels=np.arange(50, 100, 5),
                             cmap='YlGnBu',
                             extend='max',
                             alpha=0.8)
    rh_colorbar = fig.colorbar(rh_contour)
    rh_colorbar.set_label('相对湿度(%)', size=15)

    ax.barbs(u_2D['time'].values,
             u_2D['level'].values,
             np.squeeze(u_2D['data'].values.swapaxes(1, 0)) * 2.5,
             np.squeeze(v_2D['data'].values.swapaxes(1, 0)) * 2.5,
             color='k')

    TMP_contour = ax.contour(theta_e_2D['time'].values,
                             theta_e_2D['level'].values,
                             np.squeeze(theta_e_2D.values.swapaxes(1, 0)),
                             levels=np.arange(250, 450, 5),
                             colors='#F4511E',
                             linewidths=2)
    TMP_contour.clabel(TMP_contour.levels[1::2],
                       fontsize=15,
                       colors='#F4511E',
                       inline=1,
                       inline_spacing=8,
                       fmt='%i',
                       rightside_up=True,
                       use_clabeltext=True)

    xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
    ax.xaxis.set_major_formatter(xstklbls)
    for label in ax.get_xticklabels():
        label.set_rotation(30)
        label.set_fontsize(15)
        label.set_horizontalalignment('right')

    for label in ax.get_yticklabels():
        label.set_fontsize(15)

    ax.set_yscale('symlog')
    ax.set_ylabel('高度 (hPa)', fontsize=15)
    ax.set_yticklabels(np.arange(1000, 50, -100))
    ax.set_yticks(np.arange(1000, 50, -100))
    ax.set_ylim(rh_2D['level'].values.max(), rh_2D['level'].values.min())
    ax.set_xlim([rh_2D['time'].values[0], rh_2D['time'].values[-1]])

    #forecast information
    bax = plt.axes([0.10, 0.88, .25, .07], facecolor='#FFFFFFCC')
    bax.axis('off')
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(str(
        rh_2D['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    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=11)
    plt.text(2.5,
             5.0,
             '[' + str(rh_2D.attrs['model']) + ']' + '模式时间剖面',
             size=11)
    plt.text(2.5,
             2.5,
             '预报点: ' + str(rh_2D.attrs['points']['lon']) + ', ' +
             str(rh_2D.attrs['points']['lat']),
             size=11)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=11)
    utl.add_logo_extra_in_axes(pos=[0.1, 0.88, .07, .07],
                               which='nmc',
                               size='Xlarge')
    ax.set_title('相当位温, 相对湿度, 水平风', loc='right', fontsize=23)

    #出图——————————————————————————————————————————————————————————
    if (output_dir != None):
        plt.savefig(output_dir + '时间剖面产品_起报时间_' +
                    str(rh_2D['forecast_reference_time'].values)[0:13] +
                    '_预报时效_' + str(t_range[0]) + '_至_' + str(t_range[1]) +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
Beispiel #18
0
def draw_low_level_wind(uv=None,
                        wsp=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('[' + uv['model'] + '] ' + uv['lev'] + ' 风场, 风速',
              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=105,
                                      alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(ax,
                                          name='province',
                                          edgecolor='gray',
                                          lw=0.5,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='nation',
                                          edgecolor='black',
                                          lw=0.8,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='river',
                                          edgecolor='#74b9ff',
                                          lw=0.8,
                                          zorder=105,
                                          alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if wsp is not None:
        x, y = np.meshgrid(wsp['lon'], wsp['lat'])
        z = np.squeeze(wsp['data'])

        cmap = dk_ctables.cm_wind_speed_nws()
        cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)
        plots['wsp'] = ax.pcolormesh(x,
                                     y,
                                     z,
                                     cmap=cmap,
                                     zorder=90,
                                     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['udata']) * 2.5
        v = np.squeeze(uv['vdata']) * 2.5
        #plots['uv'] = ax.barbs(
        #    x, y, u, v, length=6, regrid_shape=regrid_shape,
        #    transform=datacrs, fill_empty=False, sizes=dict(emptybarb=0.05),
        #    zorder=100)

    x, y = np.meshgrid(uv['lon'], uv['lat'])
    lw = 5 * wsp['data'] / wsp['data'].max()
    plots['stream'] = ax.streamplot(x,
                                    y,
                                    uv['udata'],
                                    uv['vdata'],
                                    density=2,
                                    color='r',
                                    linewidth=lw,
                                    zorder=100,
                                    transform=datacrs)

    spd_rtio = 0.03
    for i in range(0, len(uv['lon']) - 1, 10):
        for j in range(0, len(uv['lat']) - 1, 10):
            ax.arrow(x[j, i],
                     y[j, i],
                     u[j, i] * spd_rtio,
                     v[j, i] * spd_rtio,
                     color='black',
                     zorder=100,
                     transform=datacrs,
                     width=0.05)
            #ax.quiver(x[j,i], y[j,i], x[j,i]+u[j,i]*spd_rtio, y[j,i]+v[j,i]*spd_rtio, color='black', zorder=100, transform=datacrs)
    # grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=40)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    #http://earthpy.org/cartopy_backgroung.html
    #C:\ProgramData\Anaconda3\Lib\site-packages\cartopy\data\raster\natural_earth
    ax.background_img(name='RD', resolution='high')

    #forecast information
    bax = plt.axes([0.01, 0.835, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(str(
        uv['init_time'])).replace(tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(hours=uv['fhour'])
    #发布时间
    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(uv['fhour']) + '小时', size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (wsp != None):
        cax = plt.axes([0.11, 0.06, .86, .02])
        cb = plt.colorbar(plots['wsp'],
                          cax=cax,
                          orientation='horizontal',
                          extend='max',
                          extendrect=False)
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label('(m/s)', size=20)
    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[0.85, 0.13, .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=110,
                            size=13,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[-0.01, 0.835, .1, .1],
                               which='nmc',
                               size='Xlarge')

    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '低层风_预报_' + '起报时间_' +
                    initial_time.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(uv['fhour']) + '小时' + '.png',
                    dpi=200)

    if (output_dir == None):
        plt.show()
Beispiel #19
0
def draw_Time_Crossection_rh_uv_Temp(rh_2D=None,
                                     u_2D=None,
                                     v_2D=None,
                                     TMP_2D=None,
                                     terrain_2D=None,
                                     t_range=None,
                                     model=None,
                                     output_dir=None):

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

    #   utl.add_public_title_sta(title=rh_2D.attrs['model']+'模式预报时间剖面',initial_time=rh_2D['forecast_reference_time'].values, fontsize=23)

    # Plot RH using contourf
    #rh_contour = ax.contourf(rh_2D['time'].values, rh_2D['level'].values, np.squeeze(rh_2D['data'].values.swapaxes(1,0)),
    #                        levels=np.arange(0, 106, 5), cmap='RdBu')

    startcolor = '#1E90FF'  #蓝色
    midcolor = '#F1F1F1'  #白色
    endcolor = '#696969'  #灰色
    cmap2 = col.LinearSegmentedColormap.from_list(
        'own2', [startcolor, midcolor, endcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)

    rh_2D['data'].values[rh_2D['data'].values > 100] = 100
    rh_contour = ax.contourf(rh_2D['time'].values,
                             rh_2D['level'].values,
                             np.squeeze(rh_2D['data'].values.swapaxes(1, 0)),
                             levels=np.arange(0, 101, 0.5),
                             cmap=cm.get_cmap('own2'),
                             extend='max')
    rh_colorbar = fig.colorbar(rh_contour, ticks=[20, 40, 60, 80, 100])
    rh_colorbar.set_label('相对湿度(%)', size=15)

    ax.barbs(u_2D['time'].values,
             u_2D['level'].values,
             np.squeeze(u_2D['data'].values.swapaxes(1, 0)) * 2.5,
             np.squeeze(v_2D['data'].values.swapaxes(1, 0)) * 2.5,
             color='k')

    TMP_contour = ax.contour(TMP_2D['time'].values,
                             TMP_2D['level'].values,
                             np.squeeze(TMP_2D['data'].values.swapaxes(1, 0)),
                             levels=np.arange(-100, 100, 2),
                             colors='#F4511E',
                             linewidths=1)
    TMP_contour.clabel(TMP_contour.levels[1::2],
                       fontsize=12,
                       colors='#F4511E',
                       inline=1,
                       inline_spacing=8,
                       fmt='%i',
                       rightside_up=True,
                       use_clabeltext=True)

    TMP_contour_zero = ax.contour(TMP_2D['time'].values,
                                  TMP_2D['level'].values,
                                  np.squeeze(TMP_2D['data'].values.swapaxes(
                                      1, 0)),
                                  levels=[0],
                                  colors='k',
                                  linewidths=2)
    TMP_contour_zero.clabel([0],
                            fontsize=22,
                            colors='k',
                            inline=1,
                            inline_spacing=8,
                            fmt='%i',
                            rightside_up=True,
                            use_clabeltext=True)

    startcolor = '#8B4513'  #棕色
    endcolor = '#DAC2AD'  #绿
    cmap2 = col.LinearSegmentedColormap.from_list('own3',
                                                  [endcolor, startcolor])
    # extra arguments are N=256, gamma=1.0
    cm.register_cmap(cmap=cmap2)
    if (terrain_2D.values.max() > 0):
        terrain_contour = ax.contourf(terrain_2D['time'].values,
                                      terrain_2D['level'].values,
                                      np.squeeze(
                                          terrain_2D.values.swapaxes(1, 0)),
                                      levels=np.arange(0,
                                                       terrain_2D.values.max(),
                                                       0.1),
                                      cmap=cm.get_cmap('own3'),
                                      zorder=100)

    xstklbls = mpl.dates.DateFormatter('%m月%d日%H时')
    ax.xaxis.set_major_formatter(xstklbls)
    for label in ax.get_xticklabels():
        label.set_rotation(30)
        label.set_fontsize(15)
        label.set_horizontalalignment('right')

    for label in ax.get_yticklabels():
        label.set_fontsize(15)

    ax.set_yscale('symlog')
    ax.set_ylabel('高度 (hPa)', fontsize=15)
    ax.set_yticklabels(np.arange(1000, 50, -100))
    ax.set_yticks(np.arange(1000, 50, -100))
    ax.set_ylim(rh_2D['level'].values.max(), rh_2D['level'].values.min())
    ax.set_xlim([rh_2D['time'].values[0], rh_2D['time'].values[-1]])

    #forecast information
    bax = plt.axes([0.10, 0.88, .25, .07], facecolor='#FFFFFFCC')
    bax.axis('off')
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(str(
        rh_2D['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    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=11)
    plt.text(2.5,
             5.0,
             '[' + str(rh_2D.attrs['model']) + ']' + '模式时间剖面',
             size=11)
    plt.text(2.5,
             2.5,
             '预报点: ' + str(rh_2D.attrs['points']['lon']) + ', ' +
             str(rh_2D.attrs['points']['lat']),
             size=11)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=11)
    utl.add_logo_extra_in_axes(pos=[0.1, 0.88, .07, .07],
                               which='nmc',
                               size='Xlarge')
    ax.set_title('[' + model + '] ' + '温度, 相对湿度, 水平风',
                 loc='right',
                 fontsize=23)

    #出图——————————————————————————————————————————————————————————
    if (output_dir != None):
        plt.savefig(output_dir + '时间剖面产品_起报时间_' +
                    str(rh_2D['forecast_reference_time'].values)[0:13] +
                    '_预报时效_' + str(t_range[0]) + '_至_' + str(t_range[1]) +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
Beispiel #20
0
def box_line_wsp(wsp=None, output_dir=None, points=None, extra_info=None):

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

    initTime = pd.to_datetime(str(
        wsp['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()

    # draw figure
    fig = plt.figure(figsize=(16, 4.5))
    # draw main figure
    #10米风——————————————————————————————————————
    ax = plt.axes([0.1, 0.28, .8, .62])
    utl.add_public_title_sta(
        title=wsp.attrs['model'] + '预报 ' + extra_info['point_name'] + ' [' +
        str(points['lon'][0]) + ',' + str(points['lat'][0]) + ']',
        initTime=initTime,
        fontsize=21)
    for ifhour in wsp['forecast_period'].values:
        if (ifhour == wsp['forecast_period'].values[0]):
            if (ifhour % 12 == 0):
                uv_t = (initTime +
                        timedelta(hours=ifhour)).strftime('%m月%d日%H时')
            else:
                uv_t = ' '
        else:
            if (ifhour % 12 == 0):
                uv_t = np.append(
                    uv_t,
                    (initTime + timedelta(hours=ifhour)).strftime('%m月%d日%H时'))
            else:
                uv_t = np.append(uv_t, ' ')

    labels = uv_t
    ax.boxplot(np.transpose(np.squeeze(wsp['data'].values)),
               labels=labels,
               meanline=True,
               showmeans=True,
               showfliers=False,
               whis=(0, 100))

    warning = np.zeros(len(uv_t)) + 20.
    warning_t = np.arange(0, len(uv_t)) + 1
    ax.plot(warning_t, warning, c='red', label=' ', linewidth=1)
    ax.set_ylim(0, math.ceil(wsp['data'].values.max() / 2) * 2)
    #plt.xlim(uv_t[0],uv_t[-1])
    # add legend
    #ax.legend(fontsize=15,loc='upper right')
    ax.tick_params(length=7)
    ax.tick_params(axis='y', labelsize=100)
    for label in ax.get_xticklabels():
        label.set_rotation(30)
        label.set_horizontalalignment('center')
    ax.tick_params(axis='y', labelsize=15)
    ax.tick_params(axis='x', labelsize=10)
    miloc = mpl.dates.HourLocator(byhour=(8, 11, 14, 17, 20, 23, 2, 5))  #单位是小时
    ax.xaxis.set_minor_locator(miloc)
    yminorLocator = MultipleLocator(1)  #将此y轴次刻度标签设置为1的倍数
    ax.yaxis.set_minor_locator(yminorLocator)
    ymajorLocator = MultipleLocator(2)  #将此y轴次刻度标签设置为1的倍数
    ax.yaxis.set_major_locator(ymajorLocator)
    ax.grid(axis='x', ls='--')
    for label in ax.get_yticklabels():
        label.set_fontsize(15)
    #ax.axis['left'].major_ticklabels.set_fontsize(15)
    t_gap = wsp['forecast_period'].values[1] - wsp['forecast_period'].values[0]
    ax.set_ylabel('风速 (m s$^-$$^1$)', fontsize=15)

    utl.add_logo_extra_in_axes(pos=[0.87, 0.00, .1, .1],
                               which='nmc',
                               size='Xlarge')

    #出图——————————————————————————————————————————————————————————
    if (output_dir != None):
        isExists = os.path.exists(output_dir)
        if not isExists:
            os.makedirs(output_dir)

        output_dir2 = output_dir + wsp.attrs[
            'model'] + '_起报时间_' + initTime.strftime("%Y年%m月%d日%H时") + '/'
        if (os.path.exists(output_dir2) == False):
            os.makedirs(output_dir2)

        plt.savefig(output_dir2 + wsp.attrs['model'] + '_' +
                    extra_info['point_name'] + '_' +
                    extra_info['output_head_name'] +
                    initTime.strftime("%Y%m%d%H") + '00' +
                    extra_info['output_tail_name'] + '_风速_箱线图' + '.jpg',
                    dpi=200,
                    bbox_inches='tight')
    else:
        plt.show()
def draw_Miller_Composite_Chart(fcst_info=None,
                                u_300=None,
                                v_300=None,
                                u_500=None,
                                v_500=None,
                                u_850=None,
                                v_850=None,
                                pmsl_change=None,
                                hgt_500_change=None,
                                Td_dep_700=None,
                                Td_sfc=None,
                                pmsl=None,
                                lifted_index=None,
                                vort_adv_500_smooth=None,
                                map_extent=(50, 150, 0, 65),
                                add_china=True,
                                city=True,
                                south_China_sea=True,
                                output_dir=None,
                                Global=False):
    # set font
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

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

    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.])
    datacrs = ccrs.PlateCarree()
    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)
    map_extent2 = utl.adjust_map_ratio(ax,
                                       map_extent=map_extent,
                                       datacrs=datacrs)

    #draw data
    plots = {}

    lons = fcst_info['lon']
    lats = fcst_info['lat']
    cs1 = ax.contour(lons,
                     lats,
                     lifted_index,
                     range(-8, -2, 2),
                     transform=ccrs.PlateCarree(),
                     colors='red',
                     linewidths=0.75,
                     linestyles='solid',
                     zorder=7)
    cs1.clabel(fontsize=10,
               inline=1,
               inline_spacing=7,
               fmt='%i',
               rightside_up=True,
               use_clabeltext=True)

    # Plot Surface pressure falls
    cs2 = ax.contour(lons,
                     lats,
                     pmsl_change.to('hPa'),
                     range(-10, -1, 4),
                     transform=ccrs.PlateCarree(),
                     colors='k',
                     linewidths=0.75,
                     linestyles='dashed',
                     zorder=6)
    cs2.clabel(fontsize=10,
               inline=1,
               inline_spacing=7,
               fmt='%i',
               rightside_up=True,
               use_clabeltext=True)

    # Plot 500-hPa height falls
    cs3 = ax.contour(lons,
                     lats,
                     hgt_500_change,
                     range(-60, -29, 15),
                     transform=ccrs.PlateCarree(),
                     colors='k',
                     linewidths=0.75,
                     linestyles='solid',
                     zorder=5)
    cs3.clabel(fontsize=10,
               inline=1,
               inline_spacing=7,
               fmt='%i',
               rightside_up=True,
               use_clabeltext=True)

    # Plot surface pressure
    ax.contourf(lons,
                lats,
                pmsl.to('hPa'),
                range(990, 1011, 20),
                alpha=0.5,
                transform=ccrs.PlateCarree(),
                colors='yellow',
                zorder=1)

    # Plot surface dewpoint
    ax.contourf(lons,
                lats,
                Td_sfc.to('degF'),
                range(65, 76, 10),
                alpha=0.4,
                transform=ccrs.PlateCarree(),
                colors=['green'],
                zorder=2)

    # Plot 700-hPa dewpoint depression
    ax.contourf(lons,
                lats,
                Td_dep_700,
                range(15, 46, 30),
                alpha=0.5,
                transform=ccrs.PlateCarree(),
                colors='tan',
                zorder=3)

    # Plot Vorticity Advection
    ax.contourf(lons,
                lats,
                vort_adv_500_smooth,
                range(5, 106, 100),
                alpha=0.5,
                transform=ccrs.PlateCarree(),
                colors='BlueViolet',
                zorder=4)

    # Define a skip to reduce the barb point density
    skip_300 = (slice(None, None, 12), slice(None, None, 12))
    skip_500 = (slice(None, None, 10), slice(None, None, 10))
    skip_850 = (slice(None, None, 8), slice(None, None, 8))
    x, y = np.meshgrid(fcst_info['lon'], fcst_info['lat'])
    # 300-hPa wind barbs
    jet300 = ax.barbs(x[skip_300],
                      y[skip_300],
                      u_300[skip_300].m,
                      v_300[skip_300].m,
                      length=6,
                      transform=ccrs.PlateCarree(),
                      color='green',
                      zorder=10,
                      label='300-hPa Jet Core Winds (m/s)')

    # 500-hPa wind barbs
    jet500 = ax.barbs(x[skip_500],
                      y[skip_500],
                      u_500[skip_500].m,
                      v_500[skip_500].m,
                      length=6,
                      transform=ccrs.PlateCarree(),
                      color='blue',
                      zorder=9,
                      label='500-hPa Jet Core Winds (m/s)')

    # 850-hPa wind barbs
    jet850 = ax.barbs(x[skip_850],
                      y[skip_850],
                      u_850[skip_850].m,
                      v_850[skip_850].m,
                      length=6,
                      transform=ccrs.PlateCarree(),
                      color='k',
                      zorder=8,
                      label='850-hPa Jet Core Winds (m/s)')

    #additional information
    plt.title('[' + fcst_info['model'] + '] ' + 'Miller 综合分析图',
              loc='left',
              fontsize=30)

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

    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=40)
    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

    # Legend
    purple = mpatches.Patch(color='BlueViolet',
                            label='Cyclonic Absolute Vorticity Advection')
    yellow = mpatches.Patch(color='yellow', label='Surface MSLP < 1010 hPa')
    green = mpatches.Patch(color='green', label='Surface Td > 65 F')
    tan = mpatches.Patch(color='tan',
                         label='700 hPa Dewpoint Depression > 15 C')
    red_line = lines.Line2D([], [], color='red', label='Best Lifted Index (C)')
    dashed_black_line = lines.Line2D(
        [], [],
        linestyle='dashed',
        color='k',
        label='12-hr Surface Pressure Falls (hPa)')
    black_line = lines.Line2D([], [],
                              linestyle='solid',
                              color='k',
                              label='12-hr 500-hPa Height Falls (m)')
    leg = plt.legend(handles=[
        jet300, jet500, jet850, dashed_black_line, black_line, red_line,
        purple, tan, green, yellow
    ],
                     loc=3,
                     title='Composite Analysis Valid: ',
                     framealpha=1)
    leg.set_zorder(100)

    #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(
        fcst_info['forecast_reference_time'])).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(hours=fcst_info['forecast_period'])
    #发布时间
    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(fcst_info['forecast_period']) + '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # 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=110,
                            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 + 'Miller_综合图_预报_' + '起报时间_' +
                    initTime.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(fcst_info['forecast_period']) + '小时' + '.png',
                    dpi=200,
                    bbox_inches='tight')
        plt.close()

    if (output_dir == None):
        plt.show()
def draw_PV_Div_uv(pv=None,
                   uv=None,
                   div=None,
                   map_extent=(50, 150, 0, 65),
                   regrid_shape=20,
                   add_china=True,
                   city=False,
                   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('[' + pv.attrs['model'] + '] ' + str(int(pv['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 div is not None:

        x, y = np.meshgrid(div['lon'], div['lat'])
        z = np.squeeze(div['data'])
        clevs_div = np.arange(-15, 16, 1)
        # plots['div'] = ax.contourf(
        #     x, y, z*1e5,clevs_div,cmap=plt.cm.PuOr,
        #     transform=datacrs,alpha=0.5, zorder=1,extend='both')

        cmap = dk_ctables2.ncl_cmaps('hotcolr_19lev')
        plots['div'] = ax.contourf(x,
                                   y,
                                   z * 1e5,
                                   levels=clevs_div[:],
                                   vmin=-15,
                                   vmax=15,
                                   cmap=cmap,
                                   transform=datacrs,
                                   alpha=0.5,
                                   zorder=1,
                                   extend='both')

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

    # draw -hPa geopotential height
    if pv is not None:
        x, y = np.meshgrid(pv['lon'], pv['lat'])
        clevs_pv = np.arange(4, 25, 1)
        plots['pv'] = ax.contour(x,
                                 y,
                                 np.squeeze(pv['data']) * 1e6,
                                 clevs_pv,
                                 colors='black',
                                 linewidths=2,
                                 transform=datacrs,
                                 zorder=3)
        plt.clabel(plots['pv'],
                   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(
        pv['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(hours=pv['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(pv.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (div != None):
        cax = plt.axes([l, b - 0.04, w, .02])
        cb = plt.colorbar(plots['div'],
                          cax=cax,
                          orientation='horizontal',
                          ticks=clevs_div[:],
                          extend='both',
                          extendrect=False)
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label('Divergence ($10^5$ s$^{-1}$)', 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=110,
                            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(pv.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')
        plt.close()

    if (output_dir == None):
        plt.show()
Beispiel #23
0
def draw_Rain_evo(
        rain=None,fcs_lvl=4,
        map_extent=(50, 150, 0, 65),
        regrid_shape=20,
        add_china=True,city=True,south_China_sea=True,
        output_dir=None,Global=False):
# set font
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)
    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')
# set figure
    plt.figure(figsize=(16,9))

    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)
    
    datacrs = ccrs.PlateCarree()
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    plt.title('['+rain.attrs['model']+'] 预报逐'+
        str(rain.attrs['t_gap'])+'小时'+str(fcs_lvl)+'mm降水范围演变', 
        loc='left', fontsize=30)
#draw data
    plots = {}
    if rain is not None:
        x, y = np.meshgrid(rain['lon'], rain['lat'])
        for itime in range(0,len(rain['time'].values)):
            z=np.squeeze(rain['data'].values[itime,:,:])
            z[z<=0.1]=np.nan
            initTime = pd.to_datetime(str(rain.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
            labels=(initTime+timedelta(hours=rain.coords['forecast_period'].values[itime])).strftime("%m月%d日%H时")
            cmap=mpl.cm.jet
            per_color=utl.get_part_clev_and_cmap(cmap=cmap,clev_range=[0,len(rain['time'].values)],clev_slt=itime)
            ax.contourf(
                x,y,z, levels=[fcs_lvl,800],
                colors=per_color, zorder=3,transform=datacrs,
                alpha=0.2+itime*((1-0.2)/len(rain['time'].values)))
            if(itime == 0):
                label_handles = [mpatches.Patch(color=per_color.reshape(4),
                    alpha=0.2+itime*((1-0.2)/len(rain['time'].values)), label=labels)]
            else:
                label_handles.append(mpatches.Patch(color=per_color.reshape(4),alpha=0.2+itime*((1-0.2)/len(rain['time'].values)), label=labels))
        leg = plt.legend(handles=label_handles, loc=3,framealpha=1)
#additional information
    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(
        ax, name='coastline', edgecolor='gray', lw=0.8, zorder=1,alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(
            ax, name='province', edgecolor='gray', lw=0.5, zorder=1)
        utl.add_china_map_2cartopy_public(
            ax, name='nation', edgecolor='black', lw=0.8, zorder=1)
        utl.add_china_map_2cartopy_public(
            ax, name='river', edgecolor='#74b9ff', lw=0.8, zorder=1,alpha=0.5)

    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=1)
    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(rain.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()
    fcst_time=initTime+timedelta(hours=rain.coords['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,'起始时间: '+
        (initTime+timedelta(hours=rain.coords['forecast_period'].values[0])).strftime("%Y年%m月%d日%H时"),size=15)
    plt.text(2.5, 2.5,'终止时间: '+
        (initTime+timedelta(hours=rain.coords['forecast_period'].values[1])).strftime("%Y年%m月%d日%H时"),size=15)
    plt.text(2.5, 0.5,'www.nmc.cn',size=15)

    # add color bar
    # 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=110,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(int(rain.coords['forecast_period'].values[0]))+'小时'+'.png', dpi=200)
    
    if(output_dir == None):
        plt.show()        
Beispiel #24
0
def draw_gh_uv_wvfl(gh=None,
                    uv=None,
                    wvfl=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['model'] + '] ' + gh['lev'] + 'hPa 位势高度场, ' +
              uv['lev'] + 'hPa 风场, ' + wvfl['lev'] + '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=105,
                                      alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(ax,
                                          name='province',
                                          edgecolor='gray',
                                          lw=0.5,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='nation',
                                          edgecolor='black',
                                          lw=0.8,
                                          zorder=105)
        utl.add_china_map_2cartopy_public(ax,
                                          name='river',
                                          edgecolor='#74b9ff',
                                          lw=0.8,
                                          zorder=105,
                                          alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if wvfl is not None:
        x, y = np.meshgrid(wvfl['lon'], wvfl['lat'])
        z = np.squeeze(wvfl['data']) / 10.
        #pos=[0, 2, 4, 6, 8, 10, 12, 14, 16, 20, 22]
        idx_nan = np.where(z < 5)
        z[idx_nan] = np.nan

        cmap, norm = gy_ctables.wvfl_ctable()

        cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)

        plots['wvfl'] = ax.pcolormesh(x,
                                      y,
                                      z,
                                      cmap=cmap,
                                      norm=norm,
                                      zorder=100,
                                      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['udata']) * 2.5
        v = np.squeeze(uv['vdata']) * 2.5
        plots['uv'] = ax.barbs(x,
                               y,
                               u,
                               v,
                               length=6,
                               regrid_shape=regrid_shape,
                               transform=datacrs,
                               fill_empty=False,
                               sizes=dict(emptybarb=0.05),
                               zorder=110)

    # 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=110)
        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=40)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    #http://earthpy.org/cartopy_backgroung.html
    #C:\ProgramData\Anaconda3\Lib\site-packages\cartopy\data\raster\natural_earth
    ax.background_img(name='RD', resolution='high')

    #forecast information
    bax = plt.axes([0.01, 0.835, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initial_time = pd.to_datetime(str(
        gh['init_time'])).replace(tzinfo=None).to_pydatetime()
    fcst_time = initial_time + timedelta(hours=gh['fhour'])
    #发布时间
    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(gh['fhour']) + '小时', size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (wvfl != None):
        cax = plt.axes([0.11, 0.06, .86, .02])
        cb = plt.colorbar(plots['wvfl'], cax=cax, orientation='horizontal')
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label('Water Vapor Flux (0.1g/(cm*hPa*s)', size=20)
#       cb.set_ticks([0,4,8,12,16,20,24])
#      cb.set_ticklabels(['0','4','8','12','16','20','24'])

# add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[0.85, 0.13, .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=110,
                            size=13,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[-0.01, 0.835, .1, .1],
                               which='nmc',
                               size='Xlarge')

    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '位势高度场_风场_水汽通量_预报_' + '起报时间_' +
                    initial_time.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(gh['fhour']) + '小时' + '.png',
                    dpi=200)

    if (output_dir == None):
        plt.show()
Beispiel #25
0
def draw_cumulated_precip(
        rain=None,
        map_extent=(50, 150, 0, 65),
        regrid_shape=20,
        add_china=True,city=True,south_China_sea=True,
        output_dir=None,Global=False):
# set font
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

# set figure
    fig = plt.figure(figsize=(9,14))
    camera = Camera(fig)
    nframe=rain['data'].shape[0]
    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.])

    datacrs = ccrs.PlateCarree()

    ax = plt.axes([0.01,0.1,.98,.84], projection=plotcrs)
    map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if rain is not None:
        x, y = np.meshgrid(rain['lon'], rain['lat'])
        z=np.squeeze(rain['data'].values)
        z[z<0.1]=np.nan
        znan=np.zeros(shape=x.shape)
        znan[:]=np.nan
        # cmap,norm=dk_ctables.cm_qpf_nws(atime=None,
        #         pos=np.concatenate((
        #         np.array([0, 0.1, 0.5, 1]), np.arange(2.5, 25, 2.5),
        #         np.arange(25, 50, 5), np.arange(50, 150, 10),
        #         np.arange(150, 800, 50))))
        cmap,norm=dk_ctables.cm_qpf_nws(atime=24)

        cmap.set_under(color=[0,0,0,0],alpha=0.0)
        plots['rain'] = ax.pcolormesh(
            x,y,znan, norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)
#additional information
    plt.title('['+rain.attrs['model']+'] '+
    str(int(rain.coords['forecast_period'].values[0]))+'至'+str(int(rain.coords['forecast_period'].values[-1]))+'时效累积降水预报',
        loc='left', fontsize=30)

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

    # grid lines
    gl = ax.gridlines(
        crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=1)
    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


    initTime = pd.to_datetime(
    str(rain.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime()

    #发布时间
    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')

    # add color bar
    cax=plt.axes([l,b-0.04,w,.02])
    cb = plt.colorbar(plots['rain'], cax=cax, orientation='horizontal')
    cb.ax.tick_params(labelsize='x-large')                      
    cb.set_label('Precipitation (mm)',size=20)
    fcst_time=initTime+timedelta(hours=rain.coords['forecast_period'].values[0])
    bax=plt.axes([l,b+h-0.07,.45,.07])
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])   
    fcst_time1=initTime+timedelta(hours=rain.coords['forecast_period'].values[0]-6)
    bax.text(2.5, 7.5,'起始时间: '+fcst_time1.strftime("%Y年%m月%d日%H时"),size=15)
    bax.text(2.5, 0.5,'www.nmc.cn',size=15)
    valid_fhour=bax.text(2.5, 5,'截至时间: ',size=15)
    txt_fhour=bax.text(2.5, 2.5,'预报时效: ',size=15)
    utl.add_logo_extra_in_axes(pos=[l-0.0,b+h-0.085,.1,.1],which='nmc', size='Xlarge')
    # 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=2,size=13,small_city=small_city)

    fcst_time2=initTime+timedelta(hours=rain.coords['forecast_period'].values[-1])
    valid_fhour.set_text('截至时间: '+fcst_time2.strftime("%Y年%m月%d日%H时"))
    txt_fhour.set_text('预报时效: '+str(int(rain.coords['forecast_period'].values[-1]))+'小时')
    ax.pcolormesh(
    x,y,np.squeeze(z[-1,:,:]), norm=norm,
            cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)
    
    # plt.draw()
    plt.savefig(output_dir+
        '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+
        '预报时效_'+str(int(rain.coords['forecast_period'].values[-1]))+'小时_'+rain.attrs['model']+'.png', dpi=200,bbox_inches='tight')
def OBS_Sounding_GeopotentialHeight(IR=None,
                                    Sounding=None,
                                    HGT=None,
                                    map_extent=None,
                                    city=True,
                                    south_China_sea=True,
                                    output_dir=None,
                                    Channel='C009'):

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

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

    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.])

    # draw main figure
    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)

    datacrs = ccrs.PlateCarree()

    map_extent2 = adjust_map_ratio(ax, map_extent=map_extent, datacrs=datacrs)
    # plot map background

    ax.add_feature(cfeature.OCEAN)
    add_china_map_2cartopy_public(ax,
                                  name='coastline',
                                  edgecolor='gray',
                                  lw=0.8,
                                  zorder=2,
                                  alpha=0.5)
    add_china_map_2cartopy_public(ax,
                                  name='nation',
                                  edgecolor='black',
                                  lw=0.8,
                                  zorder=2)
    add_china_map_2cartopy_public(ax,
                                  name='river',
                                  edgecolor='#74b9ff',
                                  lw=0.8,
                                  zorder=2,
                                  alpha=0.5)

    # define return plots
    plots = {}

    # draw IR
    if IR is not None:
        x, y = np.meshgrid(IR['lon'], IR['lat'])

        z = np.squeeze(IR['image'])
        if (Channel == 'C009'):
            cmap = dk_ctables.cm_wv_enhancement()
            norm, cmap = colortables.get_with_range('WVCIMSS', 160, 300)
            title_name = '水汽图像'
            plots['IR'] = ax.pcolormesh(x,
                                        y,
                                        z,
                                        norm=norm,
                                        cmap=cmap,
                                        zorder=1,
                                        transform=datacrs)

        if (Channel == 'C012'):
            cmap = dk_ctables.cm_ir_enhancement1()
            title_name = '红外(10.8微米)'
            plots['IR'] = ax.pcolormesh(x - 10.,
                                        y,
                                        z,
                                        vmin=105.,
                                        vmax=335.0,
                                        cmap=cmap,
                                        zorder=1,
                                        transform=datacrs)

        plt.title('FY4A' + title_name + '观测' + ' 探空观测 高度场',
                  loc='left',
                  fontsize=30)
        if (Sounding is not None):
            x = np.squeeze(Sounding['lon'].values)
            y = np.squeeze(Sounding['lat'].values)
            idx_vld = np.where((Sounding['Wind_angle'].values != np.nan)
                               & (Sounding['Wind_speed'].values != np.nan))
            u, v = utl.wind2UV(Winddir=Sounding['Wind_angle'].values[idx_vld],
                               Windsp=Sounding['Wind_speed'].values[idx_vld])
            idx_null = np.where((u > 100) | (v > 100))
            u[idx_null] = np.nan
            v[idx_null] = np.nan

            c_barb = {'C009': 'black', 'C012': 'white'}

            plots['uv'] = ax.barbs(x,
                                   y,
                                   u,
                                   v,
                                   transform=datacrs,
                                   fill_empty=False,
                                   sizes=dict(emptybarb=0.0),
                                   barb_increments={
                                       'half': 2,
                                       'full': 4,
                                       'flag': 20
                                   },
                                   zorder=2,
                                   color=c_barb[Channel],
                                   alpha=0.7,
                                   lw=1.5,
                                   length=7)

        # draw mean sea level pressure
        if (HGT is not None):
            x, y = np.meshgrid(HGT['lon'], HGT['lat'])
            clevs = np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))
            plots_HGT = ax.contour(x,
                                   y,
                                   ndimage.gaussian_filter(np.squeeze(
                                       HGT['data']),
                                                           sigma=1,
                                                           order=0),
                                   levels=clevs,
                                   colors='black',
                                   alpha=1,
                                   zorder=3,
                                   transform=datacrs,
                                   linewidths=3)
            ax.clabel(plots_HGT, inline=1, fontsize=20, fmt='%.0f')
            ax.contour(x,
                       y,
                       ndimage.gaussian_filter(np.squeeze(HGT['data']),
                                               sigma=1,
                                               order=0),
                       levels=[588],
                       colors='black',
                       alpha=1,
                       zorder=3,
                       transform=datacrs,
                       linewidths=6)

    #if city:
    gl = ax.gridlines(crs=datacrs,
                      linewidth=1,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=40)
    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

    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')

    IR_time = pd.to_datetime(
        IR.coords['time'].values[0]).to_pydatetime() + timedelta(hours=8)
    Sounding_time = Sounding['time'][0].to_pydatetime()
    HGT_initTime = pd.to_datetime(
        str(HGT.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    HGT_time = HGT_initTime + timedelta(
        hours=HGT.coords['forecast_period'].values[0])
    #logo
    bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])
    add_logo_extra_in_axes(pos=[l - 0.02, b + h - 0.1, .1, .1],
                           which='nmc',
                           size='Xlarge')
    bax.text(2.5,
             7.5,
             '卫星图像观测时间: ' + IR_time.strftime("%Y年%m月%d日%H时"),
             size=12)
    bax.text(2.5,
             5,
             '探空观测时间: ' + Sounding_time.strftime("%Y年%m月%d日%H时"),
             size=12)
    bax.text(2.5, 2.5, '高度场时间: ' + HGT_time.strftime("%Y年%m月%d日%H时"), size=12)
    bax.text(2.5, 0.5, 'www.nmc.cn', size=12)

    initial_time = pd.to_datetime(str(
        IR['time'].values[0])).replace(tzinfo=None).to_pydatetime()
    #发布时间
    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')

    # add color bar
    cax = plt.axes([l, b - 0.04, w, .02])
    cb = plt.colorbar(plots['IR'],
                      cax=cax,
                      orientation='horizontal',
                      extend='both',
                      extendrect=False)
    cb.ax.tick_params(labelsize='x-large')
    cb.set_label('(K)', size=10)

    # add south China sea
    if south_China_sea:
        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:
        add_city_on_map(ax,
                        map_extent=map_extent2,
                        transform=datacrs,
                        zorder=2,
                        size=16,
                        small_city=small_city)

    # show figure

    if (output_dir != None):
        plt.savefig(
            output_dir + '卫星' +
            #'_'+initial_time.strftime("%Y年%m月%d日%H时")+
            '卫星观测时间_' +
            pd.to_datetime(IR['time'].values[0]).strftime("%Y年%m月%d日%H时") +
            '.png',
            dpi=200,
            bbox_inches='tight')
        plt.close()

    if (output_dir == None):
        plt.show()
def draw_wind_temp_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 = 'black'
        c_sta_fcst = 'black'
        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=1900,
                              c='white',
                              alpha=1,
                              zorder=120)
    cmap = dk_ctables.cm_temp()
    cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)
    plots['t2m'] = ax.scatter(sta_fcs_fcst['lon'],
                              sta_fcs_fcst['lat'],
                              s=1700,
                              c=sta_fcs_fcst['TMP'],
                              vmin=-40,
                              vmax=40,
                              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=24,
                color=c_city_names,
                zorder=140)
        ax.text(sta_fcs_fcst['lon'][ista],
                sta_fcs_fcst['lat'][ista],
                '%i' % sta_fcs_fcst['TMP'][ista],
                family='SimHei',
                size=24,
                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=10,
                               linewidth=2.6,
                               transform=datacrs,
                               fill_empty=False,
                               sizes=dict(emptybarb=0.01),
                               zorder=100,
                               color=c_sta_fcst,
                               alpha=1)

        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=10,
                                   linewidth=2,
                                   transform=datacrs,
                                   fill_empty=False,
                                   sizes=dict(emptybarb=0.01),
                                   zorder=100,
                                   color='red',
                                   alpha=1)

#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('温度 ($^\circ$C)', 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_cumulative_precip_and_rain_days(cu_rain=None,
                                         days_rain=None,
                                         map_extent=(50, 150, 0, 65),
                                         regrid_shape=20,
                                         add_china=True,
                                         city=True,
                                         south_China_sea=True,
                                         output_dir=None,
                                         Global=False):
    # 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.AlbersEqualArea(central_latitude=(map_extent[2]+map_extent[3])/2.,
    #     central_longitude=(map_extent[0]+map_extent[1])/2., standard_parallels=[30., 60.])
    plotcrs = ccrs.PlateCarree()
    datacrs = ccrs.PlateCarree()

    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)
    ax.set_extent(map_extent, crs=datacrs)
    #map_extent2=utl.adjust_map_ratio(ax,map_extent=map_extent,datacrs=datacrs)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    #if(os.path.exists('L:/Temp/mask.npy')):
    #    mask=np.load('L:/Temp/mask.npy')
    #else:
    #mask=dk_mask.grid_mask_china(cu_rain['lon'], cu_rain['lat'])
    #np.save('L:/Temp/mask',mask)

    # draw -hPa geopotential height
    if days_rain is not None:
        x, y = np.meshgrid(days_rain['lon'], days_rain['lat'])
        clevs_days = np.arange(2, np.nanmax(days_rain.values) + 1)
        z = gaussian_filter(np.squeeze(days_rain.values), 5)
        #z=z*mask
        plots['days_rain'] = ax.contour(x,
                                        y,
                                        z,
                                        clevs_days,
                                        colors='black',
                                        linewidths=2,
                                        transform=datacrs,
                                        zorder=3)
        plt_lbs = plt.clabel(plots['days_rain'],
                             inline=2,
                             fontsize=20,
                             fmt='%.0f',
                             colors='black')
        clip_days = utl.gy_China_maskout(plots['days_rain'], ax, plt_lbs)
    if cu_rain is not None:
        x, y = np.meshgrid(cu_rain['lon'], cu_rain['lat'])
        z = np.squeeze(cu_rain.values)
        clevs = [50, 100, 200, 300, 400, 500, 600]
        colors = [
            '#6ab4f1', '#0001f6', '#f405ee', '#ffa900', '#fc6408', '#e80000',
            '#9a0001'
        ]
        linewidths = [1, 1, 2, 2, 3, 4, 4]
        cmap, norm = mpl.colors.from_levels_and_colors(clevs,
                                                       colors,
                                                       extend='max')
        plots['rain'] = ax.contourf(x,
                                    y,
                                    z,
                                    clevs,
                                    norm=norm,
                                    cmap=cmap,
                                    transform=datacrs,
                                    extend='max',
                                    alpha=0.1)
        plots['rain2'] = ax.contour(x,
                                    y,
                                    z,
                                    clevs,
                                    norm=norm,
                                    cmap=cmap,
                                    transform=datacrs,
                                    linewidths=linewidths)
        plt.setp(plots['rain2'].collections,
                 path_effects=[
                     path_effects.SimpleLineShadow(),
                     path_effects.Normal()
                 ])

        # plots['rain'] = ax.contourf(x,y,z,
        #     cmap=cmap, zorder=1,transform=datacrs,alpha=0.5)
        clip_rain = utl.gy_China_maskout(plots['rain'], ax)
        clip_rain2 = utl.gy_China_maskout(plots['rain2'], ax)

#additional information
    plt.title('过去' + str(int(days_rain.attrs['rn_ndays'])) + '天降水日数, ' + '过去' +
              str(int(cu_rain.attrs['cu_ndays'])) + '天累积降水量',
              loc='left',
              fontsize=30)

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

    stamen_terrain = cimg.Stamen('terrain-background')
    ax.add_image(stamen_terrain, 6)

    # grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=1)
    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')
    ax.add_feature(cfeature.LAND, color='#F5E19F')
    ax.add_feature(cfeature.OCEAN)

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

    #forecast information
    bax = plt.axes([l, b + h - 0.05, .27, .05], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(
        str(days_rain.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=days_rain.coords['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(1.5, 5.5, '观测截止时间: ' + initTime.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(1.5, 0.5, 'www.nmc.cn', size=18)

    # # add color bar
    # if(cu_rain is not None):
    #     cax=plt.axes([l,b-0.04,w,.02])
    #     cb = plt.colorbar(plots['rain2'], cax=cax, orientation='horizontal')
    #     cb.ax.tick_params(labelsize='x-large')
    #     cb.set_label('累积降水量 (mm)',size=20)

    font = FontProperties(family='Microsoft YaHei', size=16)
    ax.legend([mpatches.Patch(color=b) for b in colors], [
        '50~100 毫米', '100~200 毫米', '200-300 毫米', '300~400 毫米', '400~500 毫米',
        '500~600 毫米', '>=600毫米'
    ],
              prop=font,
              loc='lower left')

    # 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_extent,
                            transform=datacrs,
                            zorder=2,
                            size=13,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[l - 0.01, b + h - 0.05, .06, .05],
                               which='nmc',
                               size='Xlarge')

    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '总降水_' + '观测时间_' +
                    initTime.strftime("%Y年%m月%d日%H时") + '.png',
                    dpi=200,
                    bbox_inches='tight')
        plt.close()

    if (output_dir == None):
        plt.show()
Beispiel #29
0
def draw_gh_uv_VVEL(gh=None,
                    uv=None,
                    VVEL=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'].values[0])) + 'hPa 位势高度场, ' +
              str(int(uv['level'].values[0])) + '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 VVEL is not None:
        x, y = np.meshgrid(VVEL['lon'], VVEL['lat'])
        clevs_VVEL = [0.1, 4, 13, 25, 60, 120]

        clevs_VVEL = [
            -30, -20, -10, -5, -2.5, -1, -0.5, 0.5, 1, 2.5, 5, 10, 20, 30
        ]

        z = np.squeeze(VVEL['data'] / 10.)

        cmap, norm = dk_ctables.cm_vertical_velocity_nws(pos=clevs_VVEL)
        #cmap.set_under(color=[0,0,0,0],alpha=0.0)

        plots['VVEL'] = 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')

    #forecast information
    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.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=gh.coords['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.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (VVEL != None):
        cax = plt.axes([l, b - 0.04, w, .02])
        cb = plt.colorbar(plots['VVEL'],
                          cax=cax,
                          orientation='horizontal',
                          ticks=clevs_VVEL[:],
                          extend='max',
                          extendrect=False)
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label('Vertical Velocity (0.1Pa/s)', 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=110,
                            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.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')

    if (output_dir == None):
        plt.show()
Beispiel #30
0
def draw_mslp_gust10m_uv10m(gust=None,
                            mslp=None,
                            uv10m=None,
                            map_extent=(50, 150, 0, 65),
                            regrid_shape=20,
                            add_china=True,
                            city=True,
                            south_China_sea=True,
                            output_dir=None,
                            Global=False):

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

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

    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.])

    datacrs = ccrs.PlateCarree()
    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)
    map_extent2 = utl.adjust_map_ratio(ax,
                                       map_extent=map_extent,
                                       datacrs=datacrs)

    #draw data
    plots = {}
    if gust is not None:
        x, y = np.meshgrid(gust['lon'], gust['lat'])
        z = np.squeeze(gust['data'].values)
        cmap = dk_ctables.cm_wind_speed_nws()
        cmap.set_under(color=[0, 0, 0, 0], alpha=0.0)
        z[z < 7.9] = np.nan
        plots['gust'] = ax.pcolormesh(x,
                                      y,
                                      z,
                                      cmap=cmap,
                                      vmin=7.9,
                                      vmax=65,
                                      zorder=1,
                                      transform=datacrs,
                                      alpha=0.5)

    ax.quiver(x,
              y,
              np.squeeze(uv10m['u10m'].values),
              np.squeeze(uv10m['v10m'].values),
              transform=datacrs,
              regrid_shape=40,
              width=0.001)

    if mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs_mslp = np.arange(900, 1100, 2.5)
        z = gaussian_filter(np.squeeze(mslp['data']), 5)
        plots['mslp'] = ax.contour(x,
                                   y,
                                   z,
                                   clevs_mslp,
                                   colors='black',
                                   linewidths=1,
                                   transform=datacrs,
                                   zorder=2,
                                   alpha=0.5)
        cl = plt.clabel(plots['mslp'],
                        inline=1,
                        fontsize=15,
                        fmt='%.1f',
                        colors='black')
        for t in cl:
            t.set_path_effects([
                path_effects.Stroke(linewidth=3, foreground='white'),
                path_effects.Normal()
            ])
        #+画高低压中心
        res = mslp['lon'].values[1] - mslp['lon'].values[0]
        nwindow = int(9.5 / res)
        mslp_hl = np.ma.masked_invalid(mslp['data'].values).squeeze()
        local_min, local_max = utl.extrema(mslp_hl,
                                           mode='wrap',
                                           window=nwindow)
        #Get location of extrema on grid
        xmin, xmax, ymin, ymax = map_extent2
        lons2d, lats2d = x, y
        transformed = datacrs.transform_points(datacrs, lons2d, lats2d)
        x = transformed[..., 0]
        y = transformed[..., 1]
        xlows = x[local_min]
        xhighs = x[local_max]
        ylows = y[local_min]
        yhighs = y[local_max]
        lowvals = mslp_hl[local_min]
        highvals = mslp_hl[local_max]
        yoffset = 0.022 * (ymax - ymin)
        dmin = yoffset
        #Plot low pressures
        xyplotted = []
        for x, y, p in zip(xlows, ylows, lowvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:  #,fontweight='bold'
                    a = ax.text(x,
                                y,
                                'L',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))

        #Plot high pressures
        xyplotted = []
        for x, y, p in zip(xhighs, yhighs, highvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:
                    a = ax.text(x,
                                y,
                                'H',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))
        #-画高低压中心


#additional information
    plt.title('[' + mslp.attrs['model'] + '] ' + '海平面气压, ' + '过去' +
              '%i' % gust.attrs['t_gap'] + '小时10米最大阵风和10米平均风',
              loc='left',
              fontsize=30)

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

    # 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')
    ax.add_feature(cfeature.LAND, color='#F5E19F')
    ax.add_feature(cfeature.OCEAN)

    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(mslp.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=mslp.coords['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(mslp.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    if (gust != None):
        cax = plt.axes([l, b - 0.04, w, .02])
        cb = plt.colorbar(plots['gust'],
                          cax=cax,
                          orientation='horizontal',
                          extend='max',
                          ticks=[
                              8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7,
                              37, 41.5, 46.2, 51.0, 56.1, 61.3
                          ])
        cb.ax.tick_params(labelsize='x-large')
        cb.set_label('风速 (m/s)', 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 + '海平面气压_逐6小时最大风速_预报_' + '起报时间_' +
                    initTime.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(mslp.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')
        plt.close()

    if (output_dir == None):
        plt.show()