def AQI_scatter(ax,x,y,z,cmap=dk_ctables2.ncl_cmaps('hotcold_18lev'),vmin=0,vmax=100,alpha=0.8,transform=ccrs.PlateCarree(),levels=None,**kwargs): if(levels is not None): cmap,norm=cpt.generate_cmap_norm(levels,cm=cmap,extend='both') img = ax.scatter(x,y,c=z,cmap=cmap,transform=transform, norm=norm,alpha=alpha,**kwargs) else: img = ax.scatter(x,y,c=z,cmap=cmap,transform=transform, vmin=vmin, vmax=vmax,alpha=alpha,**kwargs) return img
def draw_tmp_evo( tmp=None,thr=-4, map_extent=(50, 150, 0, 65), add_china=True,city=True,south_China_sea=True, output_dir=None,Global=False): # set font initTime = pd.to_datetime(tmp.coords['forecast_reference_time'].values).replace(tzinfo=None).to_pydatetime() fhour = int(tmp['forecast_period'].values[-1]) fcstTime = initTime + timedelta(hours=fhour) title = '['+tmp.attrs['model']+'] '+str(int(tmp['level'].values[0]))+'hPa '+str(thr)+'℃等温线演变' forcast_info = '起报时间: {0:%Y}年{0:%m}月{0:%d}日{0:%H}时\n预报时间: {1:%Y}年{1:%m}月{1:%d}日{1:%H}时\n预报时效: {2}小时\nwww.nmc.cn'.format(initTime, fcstTime, fhour) fig, ax, map_extent = GF.pallete_set.Horizontal_Pallete((18, 9),map_extent=map_extent, title=title, forcast_info=forcast_info,info_zorder=1,plotcrs=None, add_china=add_china, add_city=city,south_China_sea=south_China_sea,title_fontsize=25) plots = {} label_handles=[] x, y = np.meshgrid(tmp['lon'], tmp['lat']) for itime in range(0,len(tmp['time'].values)): z=np.squeeze(tmp['data'].values[itime,:,:]) initTime = pd.to_datetime(str(tmp.coords['forecast_reference_time'].values)).replace(tzinfo=None).to_pydatetime() labels=(initTime+timedelta(hours=tmp.coords['forecast_period'].values[itime])).strftime("%m月%d日%H时") cmap=dk_ctables2.ncl_cmaps('BlueDarkRed18') per_color=utl.get_part_clev_and_cmap(cmap=cmap,clev_range=[0,len(tmp['time'].values)],clev_slt=itime) ax.contour( x,y,z, levels=[thr], colors=per_color, zorder=3,linewidths=2,linestyles='solid', transform=ccrs.PlateCarree(),alpha=1) label_handles.append(mpatches.Patch(color=per_color.reshape(4),alpha=1, label=labels)) leg = ax.legend(handles=label_handles, loc=3,framealpha=1,fontsize=10) #additional information l, b, w, h = ax.get_position().bounds # show figure if(output_dir != None): plt.savefig(output_dir+'['+tmp.attrs['model']+'] '+str(int(tmp['level'].values[0]))+'hPa '+str(thr)+'℃等温线演变_'+ '起报时间_'+initTime.strftime("%Y年%m月%d日%H时")+ '预报时效_'+str(int(tmp.coords['forecast_period'].values[0]))+'小时'+'.png', dpi=200,bbox_inches='tight') plt.close() if(output_dir == None): plt.show()
def tadv_pcolormesh(ax, x, y, z, cmap=dk_ctables2.ncl_cmaps('cmp_b2r'), vmin=-50, vmax=50, alpha=0.8, transform=ccrs.PlateCarree(), **kwargs): img = ax.pcolormesh(x, y, z, cmap=cmap, transform=transform, vmin=vmin, vmax=vmax, **kwargs) return img
def anm_pcolormesh(ax, x, y, z, cmap=dk_ctables2.ncl_cmaps('GHRSST_anomaly'), vmin=-50, vmax=50, alpha=0.8, transform=ccrs.PlateCarree(), **kwargs): img = ax.pcolormesh(x, y, z, cmap=cmap, transform=transform, vmin=vmin, vmax=vmax, **kwargs) return img
def draw_gh_anomaly_uv(gh=None, uv=None, gh_anm=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 gh_anm is not None: x, y = np.meshgrid(gh_anm['lon'], gh_anm['lat']) z = np.squeeze(gh_anm['data'].values) cmap = dk_ctables2.ncl_cmaps('GHRSST_anomaly') plots['gh_anm'] = ax.pcolormesh(x, y, z, vmin=-50, vmax=50, cmap=cmap, zorder=1, transform=datacrs, alpha=0.7) # draw -hPa wind bards if uv is not None: x, y = np.meshgrid(uv['lon'], uv['lat']) u = np.squeeze(uv['u']) * 2.5 v = np.squeeze(uv['v']) * 2.5 plots['uv'] = ax.barbs(x, y, u.values, v.values, length=6, regrid_shape=regrid_shape, transform=datacrs, fill_empty=False, sizes=dict(emptybarb=0.05), zorder=2) # draw -hPa geopotential height if gh is not None: x, y = np.meshgrid(gh['lon'], gh['lat']) clevs_gh = np.append( np.append( np.arange(0, 480, 4), np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))), np.arange(604, 2000, 8)) plots['gh'] = ax.contour(x, y, np.squeeze(gh['data']), clevs_gh, colors='black', linewidths=2, transform=datacrs, zorder=3) plt.clabel(plots['gh'], inline=1, fontsize=20, fmt='%.0f', colors='black') # grid lines gl = ax.gridlines(crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=4) gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15)) gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15)) utl.add_cartopy_background(ax, name='RD') l, b, w, h = ax.get_position().bounds #forecast information bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC') bax.set_yticks([]) bax.set_xticks([]) bax.axis([0, 10, 0, 10]) initTime = pd.to_datetime(str( gh.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 (gh_anm is not None): cax = plt.axes([l, b - 0.04, w, .02]) cb = plt.colorbar(plots['gh_anm'], cax=cax, orientation='horizontal', ticks=np.arange(-50, 51, 5), extend='both', extendrect=False) cb.ax.tick_params(labelsize='x-large') cb.set_label('gpm', 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()
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()