def add_inset(fig, extent, pos, bounds, label=None, polygon=None, anom=None, draw_cmap_y=None, hillshade=True, markup_sub=None, sub_pos=None, sub_adj=None): sub_ax = fig.add_axes(pos, projection=ccrs.Robinson(), label=label) sub_ax.set_extent(extent, ccrs.Geodetic()) sub_ax.add_feature( cfeature.NaturalEarthFeature('physical', 'ocean', '50m', facecolor='gainsboro')) sub_ax.add_feature( cfeature.NaturalEarthFeature('physical', 'land', '50m', facecolor='dimgrey')) # if anom is not None: # shape_feature = ShapelyFeature(Reader(shp_buff).geometries(), ccrs.PlateCarree(), edgecolor='black', alpha=0.5, # facecolor='black', linewidth=1) # sub_ax.add_feature(shape_feature) if polygon is None and bounds is not None: polygon = poly_from_extent(bounds) if bounds is not None: verts = mpath.Path(latlon_extent_to_robinson_axes_verts(polygon)) sub_ax.set_boundary(verts, transform=sub_ax.transAxes) if hillshade: def out_of_poly_mask(geoimg, poly_coords): poly = ot.poly_from_coords(inter_poly_coords(poly_coords)) srs = osr.SpatialReference() srs.ImportFromEPSG(54030) # put in a memory vector ds_shp = ot.create_mem_shp(poly, srs) return ot.geoimg_mask_on_feat_shp_ds(ds_shp, geoimg) def inter_poly_coords(polygon_coords): list_lat_interp = [] list_lon_interp = [] for i in range(len(polygon_coords) - 1): lon_interp = np.linspace(polygon_coords[i][0], polygon_coords[i + 1][0], 50) lat_interp = np.linspace(polygon_coords[i][1], polygon_coords[i + 1][1], 50) list_lon_interp.append(lon_interp) list_lat_interp.append(lat_interp) all_lon_interp = np.concatenate(list_lon_interp) all_lat_interp = np.concatenate(list_lat_interp) return np.array(list(zip(all_lon_interp, all_lat_interp))) img = GeoImg(fn_hs) hs_tmp = hs_land.copy() hs_tmp_nl = hs_notland.copy() mask = out_of_poly_mask(img, polygon) hs_tmp[~mask] = 0 hs_tmp_nl[~mask] = 0 sub_ax.imshow(hs_tmp[:, :], extent=ext, transform=ccrs.Robinson(), cmap=cmap2, zorder=2, interpolation='nearest') sub_ax.imshow(hs_tmp_nl[:, :], extent=ext, transform=ccrs.Robinson(), cmap=cmap22, zorder=2, interpolation='nearest') sub_ax.outline_patch.set_edgecolor('white') if anom is not None: if anom == 'dhs_1' or 'dhs_2' or 'dhs_3' or 'dhs_3': col_bounds = np.array([0, 1, 2, 3, 5, 7, 10, 15, 20]) cb = [] cb_val = np.linspace(0, 1, len(col_bounds)) for j in range(len(cb_val)): cb.append(mpl.cm.viridis(cb_val[j])) cmap_cus = mpl.colors.LinearSegmentedColormap.from_list( 'my_cb', list( zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) if anom == 'dhs_1': vals = dhs_1 elif anom == 'dhs_2': vals = dhs_2 elif anom == 'dhs_3': vals = dhs_3 elif anom == 'dhs_4': vals = dhs_4 lab = 'Number of valid observations' # elif anom == 'dt': # col_bounds = np.array([-0.3, -0.15, 0, 0.3, 0.6]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dts # lab = 'Decadal difference in temperature (K)' # # elif anom == 'dp': # col_bounds = np.array([-0.2, -0.1, 0, 0.1, 0.2]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.BrBG(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dps # lab = 'Decadal difference in precipitation (m)' # elif anom == 'du': # col_bounds = np.array([-1, -0.5, 0, 0.5, 1]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dus # lab = 'Wind speed anomaly (m s$^{-1}$)' # # elif anom == 'dz': # # col_bounds = np.array([-100, -50, 0, 50, 100]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dzs # lab = 'Geopotential height anomaly at 500 hPa (m)' # # elif anom =='dk': # # col_bounds = np.array([-200000, -100000, 0, 100000, 200000]) # cb = [] # cb_val = np.linspace(0, 1, len(col_bounds)) # for j in range(len(cb_val)): # cb.append(mpl.cm.RdBu_r(cb_val[j])) # cmap_cus = mpl.colors.LinearSegmentedColormap.from_list('my_cb', list( # zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) # # vals = dks # lab = 'Net clear-sky downwelling SW surface radiation anomaly (J m$^{-2}$)' if draw_cmap_y is not None: sub_ax_2 = fig.add_axes([0.2, draw_cmap_y, 0.6, 0.05]) sub_ax_2.set_xticks([]) sub_ax_2.set_yticks([]) sub_ax_2.spines['top'].set_visible(False) sub_ax_2.spines['left'].set_visible(False) sub_ax_2.spines['right'].set_visible(False) sub_ax_2.spines['bottom'].set_visible(False) cbaxes = sub_ax_2.inset_axes([0, 0.85, 1, 0.2], label='legend_' + label) norm = mpl.colors.Normalize(vmin=min(col_bounds), vmax=max(col_bounds)) sm = plt.cm.ScalarMappable(cmap=cmap_cus, norm=norm) sm.set_array([]) cb = plt.colorbar(sm, cax=cbaxes, ticks=col_bounds, orientation='horizontal', extend='both', shrink=0.9) # cb.ax.tick_params(labelsize=12) cb.set_label(lab) for i in range(len(tiles)): lat, lon = SRTMGL1_naming_to_latlon(tiles[i]) if group_by_spec: lat, lon, s = latlon_to_spec_center(lat, lon) else: lat = lat + 0.5 lon = lon + 0.5 s = (1, 1) # fac = 0.02 fac = 7000000. if anom == 'dhs_1': errs = errs_1 elif anom == 'dhs_2': errs = errs_2 elif anom == 'dhs_3': errs = errs_3 elif anom == 'dhs_4': errs = errs_4 if np.isnan(errs[i]): continue #need to square because Rectangle already shows a surface f = np.sqrt(((1 / min(max(errs[i], 0.25), 1)**2 - 1 / 1**2) / (1 / 0.25**2 - 1 / 1**2))) * (1 - np.sqrt(0.1)) if ~np.isnan(vals[i]) and areas[i] > 0.2: val = vals[i] val_col = max( 0.0001, min(0.9999, (val - min(col_bounds)) / (max(col_bounds) - min(col_bounds)))) col = cmap_cus(val_col) elif areas[i] <= 5: continue else: col = plt.cm.Greys(0.7) # xy = [lon,lat] xy = coordXform(ccrs.PlateCarree(), ccrs.Robinson(), np.array([lon]), np.array([lat]))[0][0:2] # sub_ax.add_patch( # mpatches.Circle(xy=xy, radius=rad, color=col, alpha=1, transform=ccrs.Robinson(), zorder=30)) xl = np.sqrt(0.1) * s[0] + f * s[0] yl = np.sqrt(0.1) * s[1] + f * s[1] sub_ax.add_patch( mpatches.Rectangle((lon - xl / 2, lat - yl / 2), xl, yl, facecolor=col, alpha=1, transform=ccrs.PlateCarree(), zorder=30)) if markup_sub is not None and anom == 'dhs_1': lon_min = np.min(list(zip(*polygon))[0]) lon_max = np.max(list(zip(*polygon))[0]) lon_mid = 0.5 * (lon_min + lon_max) lat_min = np.min(list(zip(*polygon))[1]) lat_max = np.max(list(zip(*polygon))[1]) lat_mid = 0.5 * (lat_min + lat_max) robin = np.array( list( zip([ lon_min, lon_min, lon_min, lon_mid, lon_mid, lon_max, lon_max, lon_max ], [ lat_min, lat_mid, lat_max, lat_min, lat_max, lat_min, lat_mid, lat_max ]))) if sub_pos == 'lb': rob_x = robin[0][0] rob_y = robin[0][1] ha = 'left' va = 'bottom' elif sub_pos == 'lm': rob_x = robin[1][0] rob_y = robin[1][1] ha = 'left' va = 'center' elif sub_pos == 'lt': rob_x = robin[2][0] rob_y = robin[2][1] ha = 'left' va = 'top' elif sub_pos == 'mb': rob_x = robin[3][0] rob_y = robin[3][1] ha = 'center' va = 'bottom' elif sub_pos == 'mt': rob_x = robin[4][0] rob_y = robin[4][1] ha = 'center' va = 'top' elif sub_pos == 'rb': rob_x = robin[5][0] rob_y = robin[5][1] ha = 'right' va = 'bottom' elif sub_pos == 'rm': rob_x = robin[6][0] rob_y = robin[6][1] ha = 'right' va = 'center' elif sub_pos == 'rt': rob_x = robin[7][0] rob_y = robin[7][1] ha = 'right' va = 'top' if sub_pos[0] == 'r': rob_x = rob_x - 100000 elif sub_pos[0] == 'l': rob_x = rob_x + 100000 if sub_pos[1] == 'b': rob_y = rob_y + 100000 elif sub_pos[1] == 't': rob_y = rob_y - 100000 if sub_adj is not None: rob_x += sub_adj[0] rob_y += sub_adj[1] sub_ax.text(rob_x, rob_y, markup_sub, horizontalalignment=ha, verticalalignment=va, transform=ccrs.Robinson(), color='black', fontsize=4.5, bbox=dict(facecolor='white', alpha=1, linewidth=0.35, pad=1.5), fontweight='bold', zorder=25)
# to work. See a list here: # https://scitools.org.uk/cartopy/docs/latest/crs/projections.html ax = fig.add_subplot( 111, projection=ccrs.PlateCarree(central_longitude=mean_lo)) p = plotting(ax=ax) p.plot_stations(st) ax.gridlines( crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0, color="gray", alpha=0.5, linestyle="--", ) pdf.savefig() plt.close() ### plot great circle path fig = plt.figure(figsize=(6, 6)) ax = fig.add_subplot(111, projection=ccrs.Robinson(central_longitude=mean_lo)) p = plotting(ax=ax) p.plot_paths(st) pdf.savefig() plt.close()
def test_gridliner(): ny, nx = 2, 4 plt.figure(figsize=(10, 10)) ax = plt.subplot(nx, ny, 1, projection=ccrs.PlateCarree()) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(linestyle=':') ax = plt.subplot(nx, ny, 2, projection=ccrs.OSGB(approx=False)) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(linestyle=':') ax = plt.subplot(nx, ny, 3, projection=ccrs.OSGB(approx=False)) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(ccrs.PlateCarree(), color='blue', linestyle='-') ax.gridlines(ccrs.OSGB(approx=False), linestyle=':') ax = plt.subplot(nx, ny, 4, projection=ccrs.PlateCarree()) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(ccrs.NorthPolarStereo(), alpha=0.5, linewidth=1.5, linestyle='-') ax = plt.subplot(nx, ny, 5, projection=ccrs.PlateCarree()) ax.set_global() ax.coastlines(resolution="110m") osgb = ccrs.OSGB(approx=False) ax.set_extent(tuple(osgb.x_limits) + tuple(osgb.y_limits), crs=osgb) ax.gridlines(osgb, linestyle=':') ax = plt.subplot(nx, ny, 6, projection=ccrs.NorthPolarStereo()) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(alpha=0.5, linewidth=1.5, linestyle='-') ax = plt.subplot(nx, ny, 7, projection=ccrs.NorthPolarStereo()) ax.set_global() ax.coastlines(resolution="110m") osgb = ccrs.OSGB(approx=False) ax.set_extent(tuple(osgb.x_limits) + tuple(osgb.y_limits), crs=osgb) ax.gridlines(osgb, linestyle=':') ax = plt.subplot(nx, ny, 8, projection=ccrs.Robinson(central_longitude=135)) ax.set_global() ax.coastlines(resolution="110m") ax.gridlines(ccrs.PlateCarree(), alpha=0.5, linewidth=1.5, linestyle='-') delta = 1.5e-2 plt.subplots_adjust(left=0 + delta, right=1 - delta, top=1 - delta, bottom=0 + delta)
alpha=1, linewidth=0.35, pad=1.5), fontweight='bold', zorder=25) if not main: sub_ax.outline_patch.set_edgecolor('white') else: sub_ax.outline_patch.set_edgecolor('lightgrey') #TODO: careful here! figure size determines everything else, found no way to do it otherwise in cartopy fig_width_inch = 7.2 fig = plt.figure(figsize=(fig_width_inch, fig_width_inch / 1.9716)) ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson()) ax.set_global() ax.outline_patch.set_linewidth(0) #FIGURE img = GeoImg(fn_hs) land_mask = create_mask_from_shapefile(img, fn_land) ds = gdal.Open(fn_hs) hs = ds.ReadAsArray() hs = hs.astype(float) def stretch_hs(hs, stretch_factor=1.):
import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(5.915, 3)) ax = plt.axes(projection=ccrs.Robinson()) ax.coastlines(resolution='110m') ax.gridlines()
""" ================== Image geo-location ================== Based on the matplotlib/examples/widgets/rectangle_selector.py. """ import cartopy.crs as ccrs from matplotlib.widgets import RectangleSelector import matplotlib.pyplot as plt import matplotlib.transforms as mtrans import numpy as np rob = ccrs.Robinson(central_longitude=11.25) ax = plt.axes(projection=rob) ax.set_global() ax.coastlines() extent = list(rob.x_limits) + list(rob.y_limits) # A slightly better approximation... # extent = [-13699119.4302052, 17123551.559067532, -6356356.797292399, 8605867.777293697] img = plt.imread('../resources/640px-Around_the_World_in_Eighty_Days_map.png') img = ax.imshow(img, extent=extent, transform=rob, origin='upper') # Create a separate axes for the Rectangle selector (as it needs # to extend beyond the axes clip area). ax_selector = plt.axes([0, 0, 1, 1])
# -- m. module import numpy as np import scipy.io as sio import cartopy.crs as ccrs from datetime import datetime import matplotlib.pyplot as plt #import sys; sys.path.append('/media/qliu/Zuoer_dream/mylib') #import pyutil.SMCGrid as smc from SMCPy import SMCGrid as smc # -- 1. important parms debug = 0 genGrid = 1 matFnm = 'NPAC.nc' proj = ccrs.Robinson(central_longitude=180.) #proj=ccrs.Robinson(central_longitude=0.) # -- 2. gen grid glbBathy = smc.NCBathy(matFnm, debug=debug) if genGrid: smc.GenSMCGrid(bathy_obj=glbBathy, gen_cell_sides=False, debug=debug) exit # -- 3. Create Grid from file and plot the cells smcFnm = 'NPACCell.dat' obsFnm = 'NPACObs.dat' glbSMC = smc.UnSMC(smcFnm, dlon=glbBathy.dlon, dlat=glbBathy.dlat,
def draw_gh_uv_wsp(gh=None, 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('[' + 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 wsp is not None: x, y = np.meshgrid(wsp['lon'], wsp['lat']) z = np.squeeze(wsp.values) clevs_wsp = [12, 15, 18, 21, 24, 27, 30] colors = [ "#FFF59D", "#FFEE58", "#FFCA28", "#FFC107", "#FF9800", "#FB8C00", '#E64A19', '#BF360C' ] # #RRGGBBAA cmap = ListedColormap(colors, 'wsp') idx_nan = np.where(z < clevs_wsp[0]) z[idx_nan] = np.nan cmap.set_under(color=[1, 1, 1, 0], alpha=0.0) norm = BoundaryNorm(clevs_wsp, ncolors=cmap.N, clip=False) plots['wsp'] = ax.pcolormesh(x, y, z, norm=norm, cmap=cmap, zorder=1, transform=datacrs, alpha=0.5) # draw -hPa wind bards if uv is not None: x, y = np.meshgrid(uv['lon'], uv['lat']) u = np.squeeze(uv['u']) * 2.5 v = np.squeeze(uv['v']) * 2.5 plots['uv'] = ax.barbs(x, y, u.values, v.values, length=6, regrid_shape=regrid_shape, transform=datacrs, fill_empty=False, sizes=dict(emptybarb=0.05), zorder=2) # draw -hPa geopotential height if gh is not None: x, y = np.meshgrid(gh['lon'], gh['lat']) clevs_gh = np.append( np.append( np.arange(0, 480, 4), np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))), np.arange(604, 2000, 8)) plots['gh'] = ax.contour(x, y, np.squeeze(gh['data']), clevs_gh, colors='black', linewidths=2, transform=datacrs, zorder=3) plt.clabel(plots['gh'], inline=1, fontsize=20, fmt='%.0f', colors='black') # grid lines gl = ax.gridlines(crs=datacrs, linewidth=2, color='gray', alpha=0.5, linestyle='--', zorder=4) gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15)) gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15)) utl.add_cartopy_background(ax, name='RD') l, b, w, h = ax.get_position().bounds #forecast information bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC') bax.set_yticks([]) bax.set_xticks([]) bax.axis([0, 10, 0, 10]) initTime = pd.to_datetime(str( gh.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 (wsp is not None): cax = plt.axes([l, b - 0.04, w, .02]) cb = plt.colorbar(plots['wsp'], cax=cax, orientation='horizontal', ticks=clevs_wsp[:], extend='max', extendrect=False) cb.ax.tick_params(labelsize='x-large') cb.set_label('Wind Speed (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=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_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') # 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') if (output_dir == None): plt.show()
def extract_climate_indicies(ds, timedim="time", depth_dim="st_ocean", xdim="xt_ocean", ydim="yt_ocean", temp_var="temp", area_coord="area_t", print_map=False, **kwargs): """Calculates various climate indicies from an xarray dataset. kwargs are passed to the climate indicies processing functions. Most notable right now would be the `detrend` option (disabled by default), which removes a linear trend from each gridbox before processing. """ # !!! TODO, make this work with other lon conventions like -180-180 etc. # NINO boxes NINO_boxes = { "NINO1+2": { xdim: slice(-90, -80), ydim: slice(-10, 0) }, "NINO3": { xdim: slice(-150, -90), ydim: slice(-5, 5) }, "NINO3.4": { xdim: slice(-170, -120), ydim: slice(-5, 5) }, "NINO4": { xdim: slice(-200, -150), ydim: slice(-5, 5) }, } # visualize the data to make sure that all indicies areas are covered if print_map: from xarrayutils.plotting import box_plot_dict import cartopy.crs as ccrs import matplotlib.pyplot as plt surface_fld = ds[temp_var] for slice_dim in [timedim, depth_dim]: if slice_dim in ds.dims: surface_fld = surface_fld[{slice_dim: 0}] ax = plt.axes(projection=ccrs.Robinson(180)) surface_fld.plot(ax=ax, transform=ccrs.PlateCarree()) for nb in NINO_boxes.keys(): box_plot_dict( NINO_boxes[nb], xdim=xdim, ydim=ydim, ax=ax, transform=ccrs.PlateCarree(), ) ax.set_global() ax.coastlines() # calulate indicies ds_indicies = xr.Dataset() for nb in NINO_boxes.keys(): print("Calculating %s index" % nb) box = ds.sel(**NINO_boxes[nb]) if depth_dim in ds.dims: box = box[{depth_dim: 0}] ds_indicies[nb] = calculate_ninox_index(box[temp_var], box[area_coord], **kwargs) # Calculate additional ENSO inicies print("Calculating TNI index") ds_indicies["TNI"] = ds_indicies["NINO4"] - ds_indicies["NINO1+2"] return ds_indicies
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()
npoint = 50 # random latitude, longitude and value plat = np.random.rand(npoint) * 180 - 90 plon = np.random.rand(npoint) * 360 - 180 pdata = np.random.rand(npoint) # Clear the figure plt.figure(1) plt.clf() # data coordinates: Use PlateCarree for data in lat-lon coordinates datacoord = ccrs.PlateCarree() # Projection projcoord = ccrs.PlateCarree() projcoord = ccrs.Robinson() #Setup map projection and continent outlines ax = plt.axes(projection=projcoord) # Change map extent, if needed #ax.set_extent([-180, 180, -90, 90], ccrs.PlateCarree()) # Add data points plt.scatter(plon, plat, c=pdata, s=50, marker='o', transform=datacoord) # draw parallels and meridians, but don't bother labelling them. ax.gridlines(draw_labels=False) # Add coasts and states; Use ‘110m’ or ‘50m’ resolution ax.coastlines(resolution='110m')
dsp.IRON_FLUX.plot() ## fields = ['IRON_FLUX', 'Fe_sedflux', 'Fe_ventflux', 'pfeToSed'] log_levels = [0., 0.001] for scale in 10**np.arange(-3., 1., 1.): log_levels.extend(list(np.array([3., 6., 10.]) * scale)) levels = {k: log_levels for k in fields} fig = plt.figure(figsize=(12, 6)) prj = ccrs.Robinson(central_longitude=305.0) nrow, ncol = 2, 2 gs = gridspec.GridSpec( nrows=nrow, ncols=ncol+1, width_ratios=(1, 1, 0.02), wspace=0.15, hspace=0.1, ) axs = np.empty((nrow, ncol)).astype(object) caxs= np.empty((nrow, ncol)).astype(object) for i, j in product(range(nrow), range(ncol)): axs[i, j] = plt.subplot(gs[i, j], projection=prj) cax = plt.subplot(gs[:, -1])
def meshplot_globe(mme_diff, cmap_name=plt.cm.BrBG, vmax=None, vmin=None): lono = mme_diff.getLongitude()[:] lato = mme_diff.getLatitude()[:] lon, lat = np.meshgrid(lono, lato) states_provinces = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') #clevs = np.array([-0.6,-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,.3,.4,.5,.6])*2.5 p5 = np.percentile(mme_diff.compressed(), 5) p95 = np.percentile(mme_diff.compressed(), 95) if vmin is None: vmin = -1 * max(np.abs(p5), np.abs(p95)) if vmax is None: vmax = max(np.abs(p5), np.abs(p95)) clevs = np.linspace(vmin, vmax, 13) clevs_units = clevs.copy() nmap = plt.cm.get_cmap(name=cmap_name, lut=clevs.size - 1) ocean_color = np.float64([209, 230, 241]) / 255 fig = plt.figure(figsize=(12, 12), facecolor="white") ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson()) #m = ax.contourf(lon, lat, mme_diff,clevs,transform=ccrs.PlateCarree(),cmap=nmap,extend="both") m = ax.pcolormesh(lon, lat, mme_diff, vmin=vmin, vmax=vmax, transform=ccrs.PlateCarree(), cmap=nmap) ax.coastlines() ax.set_global() #ax.gridlines(xlocs=np.arange(-180,190,10),ylocs=np.arange(-180,190,10)) ax.add_feature(cfeature.BORDERS, linewidth=0.5, linestyle='-', edgecolor='k') ax.add_feature(states_provinces, linewidth=0.5, linestyle='-', edgecolor='k') #ax.add_feature(newcoast, linewidth=0.5, linestyle='-', edgecolor='k') #ax.add_feature(newlake, linewidth=0.5, linestyle='-', edgecolor='k') ax.add_feature(cartopy.feature.LAND, color='white', zorder=0, edgecolor='k', hatch="/") ax.add_feature(cartopy.feature.OCEAN, color=ocean_color, zorder=0, edgecolor='k') ax.add_feature(cfeature.BORDERS, linewidth=0.5, linestyle='-', edgecolor='k') ax.add_feature(cartopy.feature.OCEAN, color=ocean_color, zorder=1) #ax.add_feature(newcoast, linewidth=1, linestyle='-', zorder=2,edgecolor='k') #ax.text(-122,21,var_txt+' ('+seas_txt+')',transform=ccrs.PlateCarree(),fontsize=32,fontweight="bold", \ #horizontalalignment='center', verticalalignment='center',) #ax.text(-122,17,ssp_txt,transform=ccrs.PlateCarree(),fontsize=28,fontweight="normal", \ #horizontalalignment='center', verticalalignment='center',) #cbar=plt.colorbar(m,orientation="horizontal",fraction=0.08,pad=0.04)#,ticks=clevs_units[np.arange(0,clevs_units.size+1,2)]) if ((vmin == 0) and (vmax == 365)): cbar = plt.colorbar(m, orientation="horizontal", fraction=0.08, pad=0.04, ticks=np.linspace(0, 365, 12)) cbar.ax.set_xticklabels([ "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ]) else: cbar = plt.colorbar(m, orientation="horizontal", fraction=0.08, pad=0.04) cbar.ax.tick_params(labelsize=24) shpfilename = shpreader.natural_earth(resolution='110m', category='cultural', name='admin_0_countries') reader = shpreader.Reader(shpfilename) countries = reader.records()
def get_map_projection( proj_name, central_longitude=0.0, central_latitude=0.0, false_easting=0.0, false_northing=0.0, globe=None, standard_parallels=(20.0, 50.0), scale_factor=None, min_latitude=-80.0, max_latitude=84.0, true_scale_latitude=None, latitude_true_scale=None, ### BOTH secant_latitudes=None, pole_longitude=0.0, pole_latitude=90.0, central_rotated_longitude=0.0, sweep_axis='y', satellite_height=35785831, cutoff=-30, approx=None, southern_hemisphere=False, zone=15): #### numeric UTM zone proj_name = proj_name.lower() if (proj_name == 'albersequalarea'): proj = ccrs.AlbersEqualArea(central_longitude=central_longitude, central_latitude=central_latitude, false_easting=false_easting, false_northing=false_northing, globe=globe, standard_parallels=standard_parallels) elif (proj_name == 'azimuthalequidistant'): proj = ccrs.AzimuthalEquidistant(central_longitude=central_longitude, central_latitude=central_latitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'equidistantconic'): proj = ccrs.EquidistantConic(central_longitude=central_longitude, central_latitude=central_latitude, false_easting=false_easting, false_northing=false_northing, globe=globe, standard_parallels=standard_parallels) elif (proj_name == 'lambertconformal'): proj = ccrs.LambertConformal( central_longitude=-96.0, ########## central_latitude=39.0, ########## false_easting=false_easting, false_northing=false_northing, globe=globe, secant_latitudes=None, standard_parallels=None, ## default: (33,45) cutoff=cutoff) elif (proj_name == 'lambertcylindrical'): proj = ccrs.LambertCylindrical(central_longitude=central_longitude) elif (proj_name == 'mercator'): proj = ccrs.Mercator(central_longitude=central_longitude, min_latitude=min_latitude, max_latitude=max_latitude, latitude_true_scale=latitude_true_scale, false_easting=false_easting, false_northing=false_northing, globe=globe, scale_factor=None) ######### elif (proj_name == 'miller'): proj = ccrs.Miller(central_longitude=central_longitude, globe=globe) elif (proj_name == 'mollweide'): proj = ccrs.Mollweide(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'orthographic'): proj = ccrs.Orthographic(central_longitude=central_longitude, central_latitude=central_latitude, globe=globe) elif (proj_name == 'robinson'): proj = ccrs.Robinson(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'sinusoidal'): proj = ccrs.Sinusoidal(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'stereographic'): proj = ccrs.Stereographic(central_latitude=central_latitude, central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe, true_scale_latitude=true_scale_latitude, scale_factor=scale_factor) elif (proj_name == 'transversemercator'): proj = ccrs.TransverseMercator( central_longitude=central_longitude, central_latitude=central_latitude, false_easting=false_easting, false_northing=false_northing, globe=globe, scale_factor=1.0, ########## approx=approx) elif (proj_name == 'utm'): proj = ccrs.UTM(zone, southern_hemisphere=southern_hemisphere, globe=globe) elif (proj_name == 'interruptedgoodehomolosine'): proj = ccrs.InterruptedGoodeHomolosine( central_longitude=central_longitude, globe=globe) elif (proj_name == 'rotatedpole'): proj = ccrs.RotatedPole( pole_longitude=pole_longitude, pole_latitude=pole_latitude, globe=globe, central_rotated_longitude=central_rotated_longitude) elif (proj_name == 'osgb'): proj = ccrs.OSGB(approx=approx) elif (proj_name == 'europp'): proj = ccrs.EuroPP elif (proj_name == 'geostationary'): proj = ccrs.Geostationary(central_longitude=central_longitude, satellite_height=satellite_height, false_easting=false_easting, false_northing=false_northing, globe=globe, sweep_axis=sweep_axis) elif (proj_name == 'nearsideperspective'): proj = ccrs.NearsidePerspective(central_longitude=central_longitude, central_latitude=central_latitude, satellite_height=satellite_height, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckerti'): proj = ccrs.EckertI(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckertii'): proj = ccrs.EckertII(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckertiii'): proj = ccrs.EckertIII(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckertiv'): proj = ccrs.EckertIV(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckertv'): proj = ccrs.EckertV(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'eckertvi'): proj = ccrs.EckertVI(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'equalearth'): proj = ccrs.EqualEarth(central_longitude=central_longitude, false_easting=false_easting, false_northing=false_northing, globe=globe) elif (proj_name == 'gnomonic'): proj = ccrs.Gnomonic(central_latitude=central_latitude, central_longitude=central_longitude, globe=globe) elif (proj_name == 'lambertazimuthalequalarea'): proj = ccrs.LambertAzimuthalEqualArea( central_longitude=central_longitude, central_latitude=central_latitude, globe=globe, false_easting=false_easting, false_northing=false_northing) elif (proj_name == 'northpolarstereo'): proj = ccrs.NorthPolarStereo(central_longitude=central_longitude, true_scale_latitude=true_scale_latitude, globe=globe) elif (proj_name == 'osni'): proj = ccrs.OSNI(approx=approx) elif (proj_name == 'southpolarstereo'): proj = ccrs.SouthPolarStereo(central_longitude=central_longitude, true_scale_latitude=true_scale_latitude, globe=globe) else: # This is same as "Geographic coordinates" proj = ccrs.PlateCarree(central_longitude=central_longitude, globe=globe) return proj
#cmap=make_colormap(colors_list) #cmap=mbar.colormap("H02") # cmap=cm.seismic #cmap.set_under("w",alpha=0) cmap=cm.get_cmap("rainbow_r") cmapL=cmap #cm.get_cmap("rainbow_r") vmin=0.0 vmax=2000.0 norm=Normalize(vmin=vmin,vmax=vmax) hgt=11.69*(1.0/3.0) wdt=8.27 fig=plt.figure(figsize=(wdt, hgt)) G = gridspec.GridSpec(1,1) ax=fig.add_subplot(G[0,0],projection=ccrs.Robinson()) #----------------------------- ax.set_extent([lllon,urlon,lllat,urlat],crs=ccrs.PlateCarree()) ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '10m', edgecolor='face', facecolor=land),zorder=100) # pnum=len(nums) for point in np.arange(pnum): eled=leled[point] lon =lons[point] lat =lats[point] c=cmapL(norm(eled)) #print lon,lat,pname[point][0],mean_bias ax.scatter(lon,lat,s=0.5,marker="o",zorder=110,edgecolors=c, facecolors=c,transform=ccrs.PlateCarree()) #-- im=ax.scatter([],[],c=[],cmap=cmapL,s=0.1,vmin=vmin,vmax=vmax,norm=norm)# im.set_visible(False)
def plot_map(ds: xr.Dataset, var: VarName.TYPE = None, indexers: DictLike.TYPE = None, time: TimeLike.TYPE = None, region: PolygonLike.TYPE = None, projection: str = 'PlateCarree', central_lon: float = 0.0, title: str = None, properties: DictLike.TYPE = None, file: str = None) -> Figure: """ Create a geographic map plot for the variable given by dataset *ds* and variable name *var*. Plots the given variable from the given dataset on a map with coastal lines. In case no variable name is given, the first encountered variable in the dataset is plotted. In case no *time* is given, the first time slice is taken. It is also possible to set extents of the plot. If no extents are given, a global plot is created. The plot can either be shown using pyplot functionality, or saved, if a path is given. The following file formats for saving the plot are supported: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff :param ds: the dataset containing the variable to plot :param var: the variable's name :param indexers: Optional indexers into data array of *var*. The *indexers* is a dictionary or a comma-separated string of key-value pairs that maps the variable's dimension names to constant labels. e.g. "layer=4". :param time: time slice index to plot, can be a string "YYYY-MM-DD" or an integer number :param region: Region to plot :param projection: name of a global projection, see http://scitools.org.uk/cartopy/docs/v0.15/crs/projections.html :param central_lon: central longitude of the projection in degrees :param title: an optional title :param properties: optional plot properties for Python matplotlib, e.g. "bins=512, range=(-1.5, +1.5)" For full reference refer to https://matplotlib.org/api/lines_api.html and https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.contourf.html :param file: path to a file in which to save the plot :return: a matplotlib figure object or None if in IPython mode """ if not isinstance(ds, xr.Dataset): raise NotImplementedError( 'Only gridded datasets are currently supported') var_name = None if not var: for key in ds.data_vars.keys(): var_name = key break else: var_name = VarName.convert(var) var = ds[var_name] time = TimeLike.convert(time) indexers = DictLike.convert(indexers) or {} properties = DictLike.convert(properties) or {} extents = None region = PolygonLike.convert(region) if region: lon_min, lat_min, lon_max, lat_max = region.bounds if not _check_bounding_box(lat_min, lat_max, lon_min, lon_max): raise ValueError( 'Provided plot extents do not form a valid bounding box ' 'within [-180.0,+180.0,-90.0,+90.0]') extents = [lon_min, lon_max, lat_min, lat_max] # See http://scitools.org.uk/cartopy/docs/v0.15/crs/projections.html# if projection == 'PlateCarree': proj = ccrs.PlateCarree(central_longitude=central_lon) elif projection == 'LambertCylindrical': proj = ccrs.LambertCylindrical(central_longitude=central_lon) elif projection == 'Mercator': proj = ccrs.Mercator(central_longitude=central_lon) elif projection == 'Miller': proj = ccrs.Miller(central_longitude=central_lon) elif projection == 'Mollweide': proj = ccrs.Mollweide(central_longitude=central_lon) elif projection == 'Orthographic': proj = ccrs.Orthographic(central_longitude=central_lon) elif projection == 'Robinson': proj = ccrs.Robinson(central_longitude=central_lon) elif projection == 'Sinusoidal': proj = ccrs.Sinusoidal(central_longitude=central_lon) elif projection == 'NorthPolarStereo': proj = ccrs.NorthPolarStereo(central_longitude=central_lon) elif projection == 'SouthPolarStereo': proj = ccrs.SouthPolarStereo(central_longitude=central_lon) else: raise ValueError('illegal projection: "%s"' % projection) figure = plt.figure(figsize=(8, 4)) ax = plt.axes(projection=proj) if extents: ax.set_extent(extents) else: ax.set_global() ax.coastlines() var_data = _get_var_data(var, indexers, time=time, remaining_dims=('lon', 'lat')) var_data.plot.contourf(ax=ax, transform=proj, **properties) if title: ax.set_title(title) figure.tight_layout() if file: figure.savefig(file) return figure if not in_notebook() else None
def ba_plotting( predicted_ba, masked_val_data, figure_saver, cbar_label_x_offset=None, aux0=None, aux1=None, aux0_label="", aux1_label="", filename=None, ): # date_str = "2010-01 to 2015-04" text_xy = (0.02, 0.935) fig, axes = plt.subplots( 3, 1, subplot_kw={"projection": ccrs.Robinson()}, figsize=(5.1, (2.3 + 0.01) * 3), gridspec_kw={ "hspace": 0.01, "wspace": 0.01 }, ) if not np.all(predicted_ba.mask == masked_val_data.mask): raise ValueError("Predicted BA and Val BA mask should match.") boundaries = np.geomspace(1e-5, 1e-1, 8) cmap = "inferno_r" extend = "both" plot_kwargs = dict( aux0=aux0, aux1=aux1, fig=fig, # Disable checking of the displayed bin edges, since we are sure about which # bin edges we wnat to display (the ones calculated above). cbar_format=get_sci_format(ndigits=1, atol=np.inf), cbar_pad=0.035, ) # Plotting observed. fig, _, cb0 = disc_cube_plot( dummy_lat_lon_cube(np.mean(masked_val_data, axis=0)), bin_edges=boundaries, ax=axes[0], cmap=cmap, extend=extend, cbar_label="Ob. BA", **plot_kwargs, ) # Plotting predicted. fig, _, cb1 = disc_cube_plot( dummy_lat_lon_cube(np.mean(predicted_ba, axis=0)), bin_edges=boundaries, ax=axes[1], cmap=cmap, extend=extend, cbar_label="Pr. BA", **plot_kwargs, ) frac_diffs = np.mean(masked_val_data - predicted_ba, axis=0) / np.mean( masked_val_data, axis=0) # Plotting differences. diff_boundaries = [ -(10**2), -(10**1), -(10**0), -(3 * 10**-2), 0, 3 * 10**-2, 3 * 10**-1, ] extend = "both" fig, _, cb2 = disc_cube_plot( dummy_lat_lon_cube(frac_diffs), bin_edges=diff_boundaries, ax=axes[2], cbar_label="<Ob. - Pr.> / <Ob.>", extend=extend, cmap="PuOr_r", # Add labelled rectangles only to the last plot. aux0_label=aux0_label, aux1_label=aux1_label, loc=(0.8, 0.11), height=0.02, aspect=2.5, cmap_midpoint=0, cmap_symmetric=False, **plot_kwargs, ) if cbar_label_x_offset is not None: # Manual control. max_x = 0 for cb in (cb0, cb1, cb2): bbox = cb.ax.get_position() if bbox.xmax > max_x: max_x = bbox.xmax for cb in (cb0, cb1, cb2): bbox = cb.ax.get_position() mean_y = (bbox.ymin + bbox.ymax) / 2.0 cb.ax.yaxis.set_label_coords(max_x + cbar_label_x_offset, mean_y, transform=fig.transFigure) else: fig.align_labels() for ax, title in zip(axes, ascii_lowercase): ax.text(*text_xy, f"({title})", transform=ax.transAxes) figure_saver.save_figure( fig, "ba_prediction" if filename is None else filename, sub_directory="predictions", )
""" Tests for Robinson projection. """ import numpy as np from numpy.testing import assert_almost_equal, assert_array_almost_equal import pytest import cartopy.crs as ccrs from .helpers import check_proj_params _CRS_PC = ccrs.PlateCarree() _CRS_ROB = ccrs.Robinson() # Increase tolerance if using older proj releases if ccrs.PROJ4_VERSION >= (6, 3, 1): _TRANSFORM_TOL = 7 elif ccrs.PROJ4_VERSION >= (4, 9): _TRANSFORM_TOL = 0 else: _TRANSFORM_TOL = -1 _LIMIT_TOL = -1 # if ccrs.PROJ4_VERSION < (5, 2, 0) else 7 def test_default(): robin = ccrs.Robinson() other_args = {'a=6378137.0', 'lon_0=0'} check_proj_params('robin', robin, other_args)
def pc_2_rob(self): return InterProjectionTransform(ccrs.PlateCarree(), ccrs.Robinson())
import matplotlib.pyplot as plt import cartopy.crs as ccrs plt.figure(figsize=(5.91496652704, 3)) delta = 0.125 ax = plt.axes([0+delta, 0+delta, 1-delta, 1-delta], projection=ccrs.Robinson()) #ax.set_global() ax.coastlines() ax.gridlines()
def rob_2_rob_shifted(self): return InterProjectionTransform(ccrs.Robinson(), ccrs.Robinson(central_longitude=0))
def add_inset(fig, extent, position, bounds=None, label=None, polygon=None, shades=True, hillshade=True, list_shp=None, main=False, markup=None, markpos='left', markadj=0, markup_sub=None, sub_pos='lt'): main_pos = [0.375, 0.21, 0.25, 0.25] if polygon is None and bounds is not None: polygon = poly_from_extent(bounds) if shades: shades_main_to_inset(main_pos, position, latlon_extent_to_robinson_axes_verts(polygon), label=label) sub_ax = fig.add_axes(position, projection=ccrs.Robinson(), label=label) sub_ax.set_extent(extent, ccrs.Geodetic()) sub_ax.add_feature( cfeature.NaturalEarthFeature('physical', 'ocean', '50m', facecolor='gainsboro')) sub_ax.add_feature( cfeature.NaturalEarthFeature('physical', 'land', '50m', facecolor='dimgrey')) if hillshade: def out_of_poly_mask(geoimg, poly_coords): poly = poly_from_coords(inter_poly_coords(poly_coords)) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) # put in a memory vector ds_shp = create_mem_shp(poly, srs) return geoimg_mask_on_feat_shp_ds(ds_shp, geoimg) def inter_poly_coords(polygon_coords): list_lat_interp = [] list_lon_interp = [] for i in range(len(polygon_coords) - 1): lon_interp = np.linspace(polygon_coords[i][0], polygon_coords[i + 1][0], 50) lat_interp = np.linspace(polygon_coords[i][1], polygon_coords[i + 1][1], 50) list_lon_interp.append(lon_interp) list_lat_interp.append(lat_interp) all_lon_interp = np.concatenate(list_lon_interp) all_lat_interp = np.concatenate(list_lat_interp) return np.array(list(zip(all_lon_interp, all_lat_interp))) img = GeoImg(fn_hs) hs_tmp = hs_land.copy() hs_tmp_nl = hs_notland.copy() mask = out_of_poly_mask(img, polygon) hs_tmp[~mask] = 0 hs_tmp_nl[~mask] = 0 sub_ax.imshow(hs_tmp[:, :], extent=ext, transform=ccrs.Robinson(), cmap=cmap2, zorder=2, interpolation='nearest') sub_ax.imshow(hs_tmp_nl[:, :], extent=ext, transform=ccrs.Robinson(), cmap=cmap22, zorder=2, interpolation='nearest') if main: shape_feature = ShapelyFeature(Reader(list_shp).geometries(), ccrs.PlateCarree(), alpha=1, facecolor='indigo', linewidth=0.35, edgecolor='indigo') sub_ax.add_feature(shape_feature) if bounds is not None: verts = mpath.Path(latlon_extent_to_robinson_axes_verts(polygon)) sub_ax.set_boundary(verts, transform=sub_ax.transAxes) if not main: for i in range(len(tiles)): lat, lon = SRTMGL1_naming_to_latlon(tiles[i]) if group_by_spec: lat, lon = latlon_to_spec_center(lat, lon) else: lat = lat + 0.5 lon = lon + 0.5 if label == 'Arctic West' and ((lat < 71 and lon > 60) or (lat < 76 and lon > 100)): continue if label == 'HMA' and lat >= 46: continue # fac = 0.02 fac = 1000 if areas[i] > 10: rad = 15000 + np.sqrt(areas[i]) * fac else: rad = 15000 + 10 * fac # cmin = -1 # cmax = 1 col_bounds = np.array([ -1.5, -1.1, -0.8, -0.6, -0.4, -0.2, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 ]) # col_bounds = np.array([-1, -0.7, -0.4, -0.2, -0.1, -0.05, 0.05, 0.1, 0.15, 0.2, 0.3, 0.5]) cb = [] cb_val = np.linspace(0, 1, len(col_bounds)) for j in range(len(cb_val)): cb.append(mpl.cm.RdYlBu(cb_val[j])) cmap_cus = mpl.colors.LinearSegmentedColormap.from_list( 'my_cb', list( zip((col_bounds - min(col_bounds)) / (max(col_bounds - min(col_bounds))), cb)), N=1000) if ~np.isnan(dhs[i]) and areas[i] > 0.2 and errs[ i] < 0.5: #and ((areas[i]>=5.) or label in ['Mexico','Indonesia','Africa']): dhdt = dhs[i] dhdt_col = max( 0.0001, min(0.9999, (dhdt - min(col_bounds)) / (max(col_bounds) - min(col_bounds)))) # ind = max(0, min(int((dhs[i]/20. - cmin) / (cmax - cmin) * 100), 99)) # if dhs[i]>=0: # ind = max(0, min(int((np.sqrt(dhs[i]/20.) - cmin) / (cmax - cmin) * 100), 99)) # else: # ind = max(0, min(int((-np.sqrt(-dhs[i]/20.) - cmin) / (cmax - cmin) * 100), 99)) col = cmap_cus(dhdt_col) # elif areas[i] <= 5: # continue elif areas[i] > 0.2: col = plt.cm.Greys(0.7) # col = 'black' # xy = [lon,lat] xy = coordXform(ccrs.PlateCarree(), ccrs.Robinson(), np.array([lon]), np.array([lat]))[0][0:2] sub_ax.add_patch( mpatches.Circle(xy=xy, radius=rad, facecolor=col, edgecolor='None', alpha=1, transform=ccrs.Robinson(), zorder=30)) # sub_ax.add_patch( # mpatches.Circle(xy=xy, radius=rad, facecolor='None', edgecolor='dimgrey', alpha=1, transform=ccrs.Robinson(), zorder=30)) if markup is not None: if markpos == 'left': lon_upleft = np.min(list(zip(*polygon))[0]) lat_upleft = np.max(list(zip(*polygon))[1]) else: lon_upleft = np.max(list(zip(*polygon))[0]) lat_upleft = np.max(list(zip(*polygon))[1]) robin = coordXform(ccrs.PlateCarree(), ccrs.Robinson(), np.array([lon_upleft]), np.array([lat_upleft])) rob_x = robin[0][0] rob_y = robin[0][1] size_y = 200000 size_x = 80000 * len(markup) + markadj if markpos == 'right': rob_x = rob_x - 50000 else: rob_x = rob_x + 50000 sub_ax_2 = fig.add_axes(position, projection=ccrs.Robinson(), label=label + 'markup') # sub_ax_2.add_patch(mpatches.Rectangle((rob_x, rob_y), size_x, size_y , linewidth=1, edgecolor='grey', facecolor='white',transform=ccrs.Robinson())) sub_ax_2.set_extent(extent, ccrs.Geodetic()) verts = mpath.Path(rect_units_to_verts([rob_x, rob_y, size_x, size_y])) sub_ax_2.set_boundary(verts, transform=sub_ax.transAxes) sub_ax_2.text(rob_x, rob_y + 50000, markup, horizontalalignment=markpos, verticalalignment='bottom', transform=ccrs.Robinson(), color='black', fontsize=4.5, fontweight='bold', bbox=dict(facecolor='white', alpha=1, linewidth=0.35, pad=1.5)) if markup_sub is not None: lon_min = np.min(list(zip(*polygon))[0]) lon_max = np.max(list(zip(*polygon))[0]) lon_mid = 0.5 * (lon_min + lon_max) lat_min = np.min(list(zip(*polygon))[1]) lat_max = np.max(list(zip(*polygon))[1]) lat_mid = 0.5 * (lat_min + lat_max) size_y = 150000 size_x = 150000 lat_midup = lat_min + 0.87 * (lat_max - lat_min) robin = coordXform( ccrs.PlateCarree(), ccrs.Robinson(), np.array([ lon_min, lon_min, lon_min, lon_mid, lon_mid, lon_max, lon_max, lon_max, lon_min ]), np.array([ lat_min, lat_mid, lat_max, lat_min, lat_max, lat_min, lat_mid, lat_max, lat_midup ])) if sub_pos == 'lb': rob_x = robin[0][0] rob_y = robin[0][1] ha = 'left' va = 'bottom' elif sub_pos == 'lm': rob_x = robin[1][0] rob_y = robin[1][1] ha = 'left' va = 'center' elif sub_pos == 'lm2': rob_x = robin[8][0] rob_y = robin[8][1] ha = 'left' va = 'center' elif sub_pos == 'lt': rob_x = robin[2][0] rob_y = robin[2][1] ha = 'left' va = 'top' elif sub_pos == 'mb': rob_x = robin[3][0] rob_y = robin[3][1] ha = 'center' va = 'bottom' elif sub_pos == 'mt': rob_x = robin[4][0] rob_y = robin[4][1] ha = 'center' va = 'top' elif sub_pos == 'rb': rob_x = robin[5][0] rob_y = robin[5][1] ha = 'right' va = 'bottom' elif sub_pos == 'rm': rob_x = robin[6][0] rob_y = robin[6][1] ha = 'right' va = 'center' elif sub_pos == 'rt': rob_x = robin[7][0] rob_y = robin[7][1] ha = 'right' va = 'top' if sub_pos[0] == 'r': rob_x = rob_x - 50000 elif sub_pos[0] == 'l': rob_x = rob_x + 50000 if sub_pos[1] == 'b': rob_y = rob_y + 50000 elif sub_pos[1] == 't': rob_y = rob_y - 50000 sub_ax_3 = fig.add_axes(position, projection=ccrs.Robinson(), label=label + 'markup2') # sub_ax_3.add_patch(mpatches.Rectangle((rob_x, rob_y), size_x, size_y , linewidth=1, edgecolor='grey', facecolor='white',transform=ccrs.Robinson())) sub_ax_3.set_extent(extent, ccrs.Geodetic()) verts = mpath.Path(rect_units_to_verts([rob_x, rob_y, size_x, size_y])) sub_ax_3.set_boundary(verts, transform=sub_ax.transAxes) sub_ax_3.text(rob_x, rob_y, markup_sub, horizontalalignment=ha, verticalalignment=va, transform=ccrs.Robinson(), color='black', fontsize=4.5, bbox=dict(facecolor='white', alpha=1, linewidth=0.35, pad=1.5), fontweight='bold', zorder=25) if not main: sub_ax.outline_patch.set_edgecolor('white') else: sub_ax.outline_patch.set_edgecolor('lightgrey')
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 PlotAnyMap(TheFile,TheLatList,TheLonList,TheCandData,TheUnitee,TheNamee,TheCmap,TheTypee,TheVar,TheMDI,ThePlotInfo): ''' Create a masked array of variable Plot on map Save as eps and png ''' # Create the masked array of trends MSKTheCandData=ma.masked_where(TheCandData == mdi,TheCandData) # make 2d arrays of lats and lons # nudge -2.5 degrees to make them south/west gridbox corners, not centres # add extra row/column to bound the data ArrLons,ArrLats=np.meshgrid(TheLonList,TheLatList) HalfLon=(TheLonList[1]-TheLonList[0])/2. HalfLat=(TheLatList[1]-TheLatList[0])/2. LngArrLons,LngArrLats=np.meshgrid(np.append(TheLonList-HalfLon,180.),np.append(TheLatList-HalfLat,90.)) # set up plot plt.clf() fig=plt.figure(figsize=(10,6)) plt1=plt.axes([0.05,0.12,0.9,0.8],projection=ccrs.Robinson()) # left, bottom, width, height plt1.coastlines() #plt1.set_boundary # not sure what this does? maybe useful for plotting regions? plt1.gridlines(draw_labels=False) # probably a way to specify these exactly if we want something different to default # This line background fills the land with light grey #plt1.add_feature(cpf.LAND, zorder = 0, facecolor = "0.9", edgecolor = "k") # may or may not need this ext = plt1.get_extent() # End of CARTOPY # make up a blue to red (reverse) colour map cmap=plt.get_cmap(TheCmap[0]) cmaplist=[cmap(i) for i in range(cmap.N)] #pdb.set_trace() for loo in range(np.int((cmap.N/2)-20),np.int((cmap.N/2)+20)): cmaplist.remove(cmaplist[np.int((cmap.N/2)-20)]) # remove the very pale colours in the middle if (TheCmap[1] == 'flip'): # then reverse the colours cmaplist.reverse() cmap=cmap.from_list('this_cmap',cmaplist,cmap.N) # Is there isn't a hardwired vmin and vmax then make one that is nice # nsteps always 9 to avoid toomany colours nsteps = 9 if (ThePlotInfo[2] == 0): # work out best max and min values for colourbar and try to make them 'nice # must be an odd number of steps # for less than 0.1 must be 14 or fewer steps if (TheTypee == 'anomaly'): vmax=np.int(np.ceil(np.max(abs(MSKTheCandData))*10))/10. vmin=-vmax print(vmin,vmax) # if (vmax <= 0.3): # nsteps=np.int((vmax-vmin)/0.05)+1 # elif (vmax <= 0.5): # vmax=np.ceil(np.max(abs(MSKTheCandData))/0.06)*0.06 # vmin=-vmax # nsteps=np.int((vmax-vmin)/0.06)+1 # elif (vmax <= 1.0): # vmax=np.ceil(np.max(abs(MSKTheCandData))/0.1)*0.1 # vmin=-vmax # nsteps=np.int((vmax-vmin)/0.1)+1 # elif (vmax <= 1.4): # vmax=np.ceil(np.max(abs(MSKTheCandData))/0.2)*0.2 # vmin=-vmax # nsteps=np.int((vmax-vmin)/0.2)+1 # elif (vmax > 1.4): # vmax=np.ceil(np.max(abs(MSKTheCandData))/0.3)*0.3 # vmin=-vmax # nsteps=np.int((vmax-vmin)/0.3)+1 # pdb.set_trace() # stop here and play else: # vmax=np.ceil(np.max(abs(MSKTheCandData))) # vmin=np.floor(np.min(abs(MSKTheCandData))) vmax=np.ceil(np.max(MSKTheCandData)) vmin=np.floor(np.min(MSKTheCandData)) vrange=vmax-vmin print(vmin,vmax,vrange) # if (vmax-vmin < 14): # nsteps=np.int((vmax-vmin))+1 # elif (vmax <= 21): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(1.5*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(1.5*7) # nsteps=np.int((vmax-vmin)/1.5)+1 # elif (vmax <= 30): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(2*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(2*7) # nsteps=np.int((vmax-vmin)/2)+1 # elif (vmax <= 35): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(2.5*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(2.5*7) # nsteps=np.int((vmax-vmin)/2.5)+1 # elif (vmax <= 42): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(3*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(3*7) # nsteps=np.int((vmax-vmin)/3)+1 # elif (vmax <= 56): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(4*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(4*7) # nsteps=np.int((vmax-vmin)/4)+1 # elif (vmax <= 70): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(5*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(5*7) # nsteps=np.int((vmax-vmin)/5)+1 # elif (vmax <= 84): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(6*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(6*7) # nsteps=np.int((vmax-vmin)/6)+1 # elif (vmax <= 98): # vmax=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))+(7*7) # vmin=(np.floor(np.min(abs(MSKTheCandData)))+(vrange/2.))-(7*7) # nsteps=np.int((vmax-vmin)/7)+1 # pdb.set_trace() # stop here and play else: vmin = ThePlotInfo[0] vmax = ThePlotInfo[1] nsteps = ThePlotInfo[2] print(vmin,vmax,nsteps) bounds=np.linspace(vmin,vmax,nsteps) strbounds=["%4.1f" % i for i in bounds] norm=mpl_cm.colors.BoundaryNorm(bounds,cmap.N) # Only pcolor can do boxing on masked arrays, not really sure why we use pcolormesh at all grids = plt1.pcolor(LngArrLons,LngArrLats,MSKTheCandData,transform = ccrs.PlateCarree(),cmap=cmap,norm=norm) # grids=m.pcolor(LngArrLons,LngArrLats,MSKTheCandData,cmap=cmap,norm=norm,latlon='TRUE') cbax=fig.add_axes([0.05,0.08,0.9,0.03]) cb=plt.colorbar(grids,cax=cbax,orientation='horizontal',ticks=bounds) #, extend=extend cb.ax.tick_params(labelsize=12) plt.figtext(0.5,0.01,TheVar+' ('+TheUnitee+')',size=14,ha='center') # add labals and watermark # watermarkstring="/".join(os.getcwd().split('/')[4:])+'/'+os.path.basename( __file__ )+" "+dt.datetime.strftime(dt.datetime.now(), "%d-%b-%Y %H:%M") # plt.figtext(0.01,0.01,watermarkstring,size=6) plt.figtext(0.5,0.95,TheNamee,size=16,ha='center') # If a letter is supplied then print on plot if (ThePlotInfo[3] != ' '): plt.figtext(0.1,0.92,ThePlotInfo[3],size=16,ha='center') # plt.show() # stop() plt.savefig(TheFile+".eps") plt.savefig(TheFile+".png") plt.clf() return #PlotAnyMap
import geopandas import alphashape try: DATA = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data')) except NameError: DATA = os.path.abspath(os.path.join(os.path.dirname(os.getcwd()), 'examples', 'data')) # Define input points gdf = geopandas.read_file(os.path.join(DATA, 'Public_Airports_March2018.shp')) # Generate the alpha shape alpha_shape = alphashape.alphashape(gdf) # Initialize plot ax = plt.axes(projection=ccrs.PlateCarree()) # Plot input points gdf_proj = gdf.to_crs(ccrs.Robinson().proj4_init) ax.scatter([p.x for p in gdf_proj['geometry']], [p.y for p in gdf_proj['geometry']], transform=ccrs.Robinson()) # Plot alpha shape ax.add_geometries( alpha_shape.to_crs(ccrs.Robinson().proj4_init)['geometry'], crs=ccrs.Robinson(), alpha=.2) plt.show()
def time_ocean_rob(): ccrs.Robinson().project_geometry(OCEAN.geoms)
p = twelve_climatologies.plot.contourf( transform=ccrs.PlateCarree(), col='month', col_wrap=2, sharex=True, sharey=True, extend='both', #figsize=(5,6), levels=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 200, 300, 500], cmap='jet', cbar_kwargs={ 'spacing': 'uniform', 'shrink': 0.80, 'orientation': 'horizontal', 'pad': 0.05 }, infer_intervals=True, subplot_kws={"projection": ccrs.Robinson()}) for ax in p.axes.flat: ax.coastlines() #ax.set_aspect("equal") p.fig.savefig(surf_path + '/' + variable + '_twelve_clim_ORCA-0.25x0.25_regular_1979_2017.png', dpi=300, transparent=True, bbox_inches='tight') #plt.show() ds.close()
def map_robustness(signal, high_agreement_mask, low_agreement_mask, variable=None, cmap='seismic', title=None, file_extension='png'): """ generates a graphic for the output of the ensembleRobustness process for a lat/long file. :param signal: netCDF file containing the signal difference over time :param highagreement: :param lowagreement: :param variable: :param cmap: default='seismic', :param title: default='Model agreement of signal' :returns str: path/to/file.png """ from blackswan import utils from numpy import mean, ma if variable is None: variable = utils.get_variable(signal) try: var_signal = utils.get_values(signal) mask_l = utils.get_values(low_agreement_mask) mask_h = utils.get_values(high_agreement_mask) # mask_l = ma.masked_where(low < 0.5, low) # mask_h = ma.masked_where(high < 0.5, high) # mask_l[mask_l == 0] = np.nan # mask_h[mask_h == 0] = np.nan LOGGER.info('data loaded') lats, lons = utils.get_coordinates(signal, unrotate=True) if len(lats.shape) == 1: cyclic_var, cyclic_lons = add_cyclic_point(var_signal, coord=lons) mask_l, cyclic_lons = add_cyclic_point(mask_l, coord=lons) mask_h, cyclic_lons = add_cyclic_point(mask_h, coord=lons) lons = cyclic_lons.data var_signal = cyclic_var LOGGER.info('lat lon loaded') minval = round(np.nanmin(var_signal)) maxval = round(np.nanmax(var_signal)+.5) LOGGER.info('prepared data for plotting') except: msg = 'failed to get data for plotting' LOGGER.exception(msg) raise Exception(msg) try: fig = plt.figure(facecolor='w', edgecolor='k') ax = plt.axes(projection=ccrs.Robinson(central_longitude=int(mean(lons)))) norm = MidpointNormalize(midpoint=0) cs = plt.contourf(lons, lats, var_signal, 60, norm=norm, transform=ccrs.PlateCarree(), cmap=cmap, interpolation='nearest') cl = plt.contourf(lons, lats, mask_l, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '/']) ch = plt.contourf(lons, lats, mask_h, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '.']) # artists, labels = ch.legend_elements() # plt.legend(artists, labels, handleheight=2) # plt.clim(minval,maxval) ax.coastlines() ax.gridlines() # ax.set_global() if title is None: plt.title('%s with Agreement' % variable) else: plt.title(title) plt.colorbar(cs) plt.annotate('// = low model ensemble agreement', (0, 0), (0, -10), xycoords='axes fraction', textcoords='offset points', va='top') plt.annotate('.. = high model ensemble agreement', (0, 0), (0, -20), xycoords='axes fraction', textcoords='offset points', va='top') graphic = fig2plot(fig=fig, file_extension=file_extension) plt.close() LOGGER.info('Plot created and figure saved') except: msg = 'failed to plot graphic' LOGGER.exception(msg) return graphic
color2 = mpl.colors.to_rgba('white') cmap2 = mpl.colors.LinearSegmentedColormap.from_list('my_cmap2', [color1, color2], 256) cmap2._init() cmap2._lut[0:1, -1] = 0.0 # We made transparent de 10 first levels of hillshade, cmap2._lut[1:, -1] = 0.35 cmap22 = mpl.colors.LinearSegmentedColormap.from_list('my_cmap22', [color1, color2], 256) cmap22._init() cmap22._lut[0:1, -1] = 0.0 # We made transparent de 10 first levels of hillshade, cmap22._lut[1:, -1] = 0.10 axleg5 = fig.add_axes([-0.32, -0.42, 1, 1], projection=ccrs.Robinson(), label='legend_5') axleg5.set_extent([-179.99, 179.99, -89.99, 89.99], ccrs.Geodetic()) axleg5.outline_patch.set_linewidth(0) axleg5.add_patch( mpatches.Rectangle((-250000 + 5000000, -250000), 500000, 500000, edgecolor='black', linewidth=0.35, transform=ccrs.Robinson(), facecolor='None', alpha=1)) axleg5.text(5000000,