def test_LatitudeFormatter(): formatter = LatitudeFormatter() p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-90, -60, -30, 0, 30, 60, 90] result = [formatter(tick) for tick in test_ticks] expected = [u'90\u00B0S', u'60\u00B0S', u'30\u00B0S', u'0\u00B0', u'30\u00B0N', u'60\u00B0N', u'90\u00B0N'] assert_equal(result, expected)
def test_LatitudeFormatter_small_numbers(): formatter = LatitudeFormatter(number_format='.7f') p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [40.1275150, 40.1275152, 40.1275154] result = [formatter(tick) for tick in test_ticks] expected = [u'40.1275150\u00B0N', u'40.1275152\u00B0N', u'40.1275154\u00B0N'] assert result == expected
def test_LatitudeFormatter_degree_symbol(): formatter = LatitudeFormatter(degree_symbol='') p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-90, -60, -30, 0, 30, 60, 90] result = [formatter(tick) for tick in test_ticks] expected = [u'90S', u'60S', u'30S', u'0', u'30N', u'60N', u'90N'] assert result == expected
def test_LatitudeFormatter_number_format(): formatter = LatitudeFormatter(number_format='.2f') p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-90, -60, -30, 0, 30, 60, 90] result = [formatter(tick) for tick in test_ticks] expected = [u'90.00\u00B0S', u'60.00\u00B0S', u'30.00\u00B0S', u'0.00\u00B0', u'30.00\u00B0N', u'60.00\u00B0N', u'90.00\u00B0N'] assert result == expected
def test_LatitudeFormatter_mercator(): formatter = LatitudeFormatter() p = ccrs.Mercator() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-15496570.739707904, -8362698.548496634, -3482189.085407435, 0.0, 3482189.085407435, 8362698.548496634, 15496570.739707898] result = [formatter(tick) for tick in test_ticks] expected = [u'80\u00B0S', u'60\u00B0S', u'30\u00B0S', u'0\u00B0', u'30\u00B0N', u'60\u00B0N', u'80\u00B0N'] assert result == expected
def plot_obs_stats_r(out_dir,lon_stat,lat_stat,var,val_stat,run,nwshelf=True): land_50 = fill_land_cfeature() VAR_4PLOT = var_inObs4plot(var) # includes the mean values; not relevant to plot the relative change as it should be =0 if nwshelf is True: lon, lat, bat = get_contours_NWS_bat() levels = [40,80,120,240] print('[INFO] Domain is NWshelf') if nwshelf is not True: lon, lat, bat = get_contours_GBL_bat() levels = [200,500,1000,2000,3000,4000,5000] print('[INFO] Domain is GBL') VAR = get_dict() for ii,stat in enumerate(VAR_4PLOT): if len(VAR_4PLOT) == 5 and ii == 0: # jump plotting relative mean values continue else: # Iterate over the different stats that can be plotted rr = val_stat[ii] fig2 = plt.figure() #axes = fig2.add_subplot(111,projection=ccrs.PlateCarree()) axes = fig2.add_subplot(111,projection=ccrs.Mercator()) a = axes.contour(lon,lat,bat, levels, colors='grey',linewidths=.25,transform = transform) axes.coastlines(resolution='50m', color='black', linewidths=1) axes.add_feature(land_50, zorder=1) if nwshelf is True: axes.clabel(a, inline=True, fmt = '%3.0f', fontsize=6) e = axes.scatter(lon_stat,lat_stat,c=rr,s=(np.ones((1,len(rr))))*12,cmap='seismic',\ vmin=VAR[stat]['limits_diff'][0],vmax=VAR[stat]['limits_diff'][1], transform = transform,zorder=2) cbar = fig2.colorbar(e,extend='both') axes.scatter(lon_stat,lat_stat,c='k',marker="x",s=0.6,transform = transform,zorder=3) if nwshelf is not True: e = axes.scatter(lon_stat,lat_stat,c=rr,s=(np.ones((1,len(rr))))*2,cmap='seismic',\ vmin=VAR[stat]['limits_diff'][0],vmax=VAR[stat]['limits_diff'][1], transform = transform,zorder=2) cbar = fig2.colorbar(e,shrink=0.7,extend='both') #axes.scatter(lon_stat,lat_stat,c='k',marker="x",s=0.4,zorder=3) #cbar.set_label(VAR[stat]['short_n']) #axes.gridlines() axes.set_axisbelow(True) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() axes.xaxis.set_major_formatter(lon_formatter) axes.yaxis.set_major_formatter(lat_formatter) if nwshelf is True: axes.set_xticks([-12,-6,0,6],crs=ccrs.PlateCarree()) axes.set_yticks([48,54,60],crs=ccrs.PlateCarree()) # axes.set_xlim([-13,9]) # axes.set_ylim([45,63]) axes.set_extent([-14,11,45,63],crs=ccrs.PlateCarree()) plt.title(VAR[stat]['short_n']+' for '+run+' relative to ctr',fontsize=8) out_name2 = join(out_dir,run+'_relative2ctrl_'+stat+'.png') print("Saving figure " +out_name2) plt.savefig(out_name2,bbox_inches="tight", pad_inches=0.1,dpi=300) plt.close() return
def plot_panel(n, fig, proj, var, clevels, cmap, title, parameters, stats=None): # var_min = float(var.min()) # var_max = float(var.max()) # var_mean = cdutil.averager(var, axis='xy', weights='generate') # var = add_cyclic(var) var.getLongitude() lat = var.getLatitude() plev = var.getLevel() var = ma.squeeze(var.asma()) # Contour levels levels = None norm = None if len(clevels) > 0: levels = [-1.0e8] + clevels + [1.0e8] norm = colors.BoundaryNorm(boundaries=levels, ncolors=256) # Contour plot ax = fig.add_axes(panel[n], projection=proj) cmap = get_colormap(cmap, parameters) p1 = ax.contourf( lat, plev, var, # transform=ccrs.PlateCarree(), norm=norm, levels=levels, cmap=cmap, extend='both', ) ax.set_aspect('auto') # ax.coastlines(lw=0.3) if title[0] is not None: ax.set_title(title[0], loc='left', fontdict=plotSideTitle) if title[1] is not None: ax.set_title(title[1], fontdict=plotTitle) if title[2] is not None: ax.set_title(title[2], loc='right', fontdict=plotSideTitle) # ax.set_xticks([0, 60, 120, 180, 240, 300, 359.99], crs=ccrs.PlateCarree()) # ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree()) ax.set_xticks([-90, -60, -30, 0, 30, 60, 90]) # , crs=ccrs.PlateCarree()) ax.set_xlim(-90, 90) # lon_formatter = LongitudeFormatter( # zero_direction_label=True, number_format='.0f') LatitudeFormatter() # ax.xaxis.set_major_formatter(lon_formatter) # ax.xaxis.set_major_formatter(lat_formatter) ax.tick_params(labelsize=8.0, direction='out', width=1) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.invert_yaxis() # Color bar cbax = fig.add_axes( (panel[n][0] + 0.6635, panel[n][1] + 0.0215, 0.0326, 0.1792)) cbar = fig.colorbar(p1, cax=cbax) w, h = get_ax_size(fig, cbax) if levels is None: cbar.ax.tick_params(labelsize=9.0, length=0) else: maxval = np.amax(np.absolute(levels[1:-1])) if maxval < 10.0: fmt = "%5.2f" pad = 25 elif maxval < 100.0: fmt = "%5.1f" pad = 25 else: fmt = "%6.1f" pad = 30 cbar.set_ticks(levels[1:-1]) labels = [fmt % l for l in levels[1:-1]] cbar.ax.set_yticklabels(labels, ha='right') cbar.ax.tick_params(labelsize=9.0, pad=pad, length=0) # Min, Mean, Max fig.text(panel[n][0] + 0.6635, panel[n][1] + 0.2107, "Max\nMean\nMin", ha='left', fontdict=plotSideTitle) fig.text(panel[n][0] + 0.7635, panel[n][1] + 0.2107, "%.2f\n%.2f\n%.2f" % stats[0:3], ha='right', fontdict=plotSideTitle) # RMSE, CORR if len(stats) == 5: fig.text(panel[n][0] + 0.6635, panel[n][1] - 0.0105, "RMSE\nCORR", ha='left', fontdict=plotSideTitle) fig.text(panel[n][0] + 0.7635, panel[n][1] - 0.0105, "%.2f\n%.2f" % stats[3:5], ha='right', fontdict=plotSideTitle)
def plot_ppi_map(fig, ax, cx, lon, lat, radar_data, title=None, normvar=None, cmap=None, \ cmap_bins=16, extend=None, projection=ccrs.PlateCarree(), orient="vertical", \ clabel=None, continuously=False): """ 显示带底图的雷达图像 :param fig:matplotlib的fig对象 :param ax: axes对象 :param cx:colorbar axes对象 :param lon: 经度网格 :param lat: 纬度网格 :param radar_data: 雷达数据产品 :param title: 画图的title :param normvar: cmap的最小最大值 :param cmap:cmap的类型 :param cmap_bins: cmap分多少段 :param extend: 图像的lat lon的范围(minlon, maxlon, minlat, maxlat) :param projection: 地图的投影方式 :param orient: colorbar的朝向 :param clabel: colorbar的title :param continuously:使用采用连续的colorbar :return: """ if normvar is None: vmin = -5 vmax = 75 else: vmin, vmax = normvar if extend is None: min_lon = np.min(lon) max_lon = np.max(lon) min_lat = np.min(lat) max_lat = np.max(lat) else: min_lon, max_lon, min_lat, max_lat = extend if title is None: title = "" if clabel is None: clabel = "" if continuously: cmap_bins = 256 cmaps = plt.get_cmap(cmap) levels = MaxNLocator(nbins=cmap_bins).tick_values(vmin, vmax) norm = BoundaryNorm(levels, ncolors=cmaps.N, clip=True) ax.set_global() pm = ax.pcolormesh(lon, lat, radar_data, transform=projection, cmap=cmap, norm=norm, zorder=4) ax.add_feature(cfeature.OCEAN.with_scale('50m'), zorder=0) ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '50m',\ edgecolor='none', facecolor="white"), zorder=1) ax.add_feature(cfeature.LAKES.with_scale('50m'), zorder=2) ax.add_feature(cfeature.RIVERS.with_scale('50m'), zorder=3) ax.set_extent([min_lon, max_lon, min_lat, max_lat], projection) ax.add_feature(cfeature.ShapelyFeature(CN_shp_info.geometries(), projection,\ edgecolor='k', facecolor='none'), linewidth=0.5, \ linestyle='-' , zorder=5, alpha=0.8) if continuously: cbar = fig.colorbar(mappable=pm, cax=cx, ax=ax, orientation=orient) else: cbar = fig.colorbar(mappable=pm, cax=cx, ax=ax, orientation=orient, ticks=levels) cbar.set_ticklabels(RadarGraphMap._FixTicks(levels)) cbar.set_label(clabel) ax.set_aspect("equal") ax.set_title(title, fontsize=15) parallels = np.arange(int(min_lat), math.ceil(max_lat) + 1, 1) meridians = np.arange(int(min_lon), math.ceil(max_lon) + 1, 1) ax.set_xticks(meridians, crs=projection) ax.set_yticks(parallels, crs=projection) lon_formatter = LongitudeFormatter() lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter)
def test_LatitudeFormatter_bad_projection(): formatter = LatitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) message = 'This formatter cannot be used with non-rectangular projections.' with pytest.raises(TypeError, message=message): formatter(0)
def PlotPoVCompositesDiffENSOZPF(var, lat, lon, title, filename): var_keys = [*var] #print(var_keys) tit = ['All', 'El Ninio', 'La Ninia'] proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) for i in range(3): ax = plt.subplot(3, 1, i + 1, projection=proj) clevs = np.arange(-60, 70, 10) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var[var_keys[i * 3]], clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) lat1 = lat[lat < 0] u = var[var_keys[i * 3 + 1]][lat1 < -18, :] v = var[var_keys[i * 3 + 2]][lat1 < -18, :] lat1 = lat1[lat1 < -18] M = np.sqrt(np.add(np.power(u, 2), np.power(v, 2))) < 0.07 #mask array u_mask = ma.array(u, mask=M) v_mask = ma.array(v, mask=M) ax.quiver(lon[2:-1:6], lat1[2:-1:6], u_mask[2:-1:6, 2:-1:6], v_mask[2:-1:6, 2:-1:6], transform=ccrs.PlateCarree(), angles='xy', headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title(tit[i]) plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def test_LatitudeFormatter_minutes_seconds(test_ticks, expected): formatter = LatitudeFormatter(dms=True, auto_hide=True) formatter.set_locs(test_ticks) result = [formatter(tick) for tick in test_ticks] assert result == expected
def plt_WndBarb(XIn, YIn, U, V, timestr): fig = plt.figure() ax = fig.add_axes([0.1, 0.1, 0.70, 0.75],projection=ccrs.PlateCarree()) # ax = plt.subplot(1,1,1,projection=ccrs.PlateCarree()) Map.readshapefile(os.path.join(shpDir,'bou2_4p'), name='whatever', drawbounds=True, linewidth=0.5, color='black') ax.barbs(XIn, YIn, U, V, length=5, pivot='tip', flagcolor='r', barbcolor=['b', 'b'], barb_increments=dict(half=1, full=2, flag=10)) # 标注经纬度坐标轴 ax.set_xticks([106, 108, 110, 112], crs=ccrs.PlateCarree()) ax.set_yticks([21, 23, 25, 27], crs=ccrs.PlateCarree()) # zero_direction_label用来设置经度的0度加不加E和W lon_formatter = LongitudeFormatter(zero_direction_label=False) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) axm = plt.gca() xlim, ylim = axm.get_xlim(), axm.get_ylim() fcstdates = timestr[:8]+'_'+timestr[8:10] hours = timestr[-3:] if int(hours) < 100: hours = hours[1:] plt.text(xlim[0]+(xlim[1]-xlim[0])*0.25, ylim[1]+(ylim[1]-ylim[0])*0.08, u'广 西 全 区 未 来 '+hours+u' 小 时 10m 风 场 预 报', fontproperties=MYFONT_TITLE) plt.text(xlim[0]+(xlim[1]-xlim[0])*0.02, ylim[1]+(ylim[1]-ylim[0])*0.02, u'起 报 时 间 :'+fcstdates, fontproperties=MYFONT) # 添加风羽图例 naxes = len(grade_label) fig.subplots_adjust(top=0.75, bottom=0.15, left=0.78, right=0.95) for iplt in range(naxes): axn = fig.add_subplot(naxes, 1, iplt+1) axn.set_xlim(0.0,1.0) axn.set_ylim(0.0,1.0) if iplt == 0: axn.barbs(0.5,0.5,0.0,0.0, flagcolor='r', barbcolor=['b', 'b'], barb_increments=dict(half=1, full=2, flag=10)) # 绘制0级风,散点图 tm = plt.gca() xlim, ylim = tm.get_xlim(), tm.get_ylim() plt.text((xlim[1]-xlim[0])*0.20, ylim[1]+(ylim[1]-ylim[0])*0.15,u'风 速 : 米每秒',fontproperties=MYFONT) elif iplt == 1: line, = axn.plot([0.26,0.5], [0.5,0.5], '-', color='b') # 绘制1级风,直线图 else: x = (iplt-1)* 1.0 axn.barbs(0.5,0.5,x,0.0, flagcolor='r', barbcolor=['b', 'b'], barb_increments=dict(half=1, full=2, flag=10)) axn.text(0.60,0.36,grade_label[iplt]) axn.xaxis.set_visible(False) axn.yaxis.set_visible(False) axn.set_frame_on(False) # plt.show() flename = timestr + '_' + 'Windbarb.png' OutFigPath = os.path.join(OutFigDir,fcstdates) if not os.path.exists(OutFigPath): os.makedirs(OutFigPath) plt.savefig(OutFigPath+'/'+flename, bbox_inches='tight', pad_inches=0.3, dpi=300) plt.clf() plt.close(fig)
def mapper(self,z = None,extent=None,vmin=None,vmax=None,cmap='cividis',box=False): """ This method creates a cartopy map of the data held in the xrds. z is what is desired to be plotted at each lat and lon pair. If z is none, then it will default to just showing where all the footprints are. """ #import cartopy stuff import cartopy import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.ticker as mticker from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER import cartopy.io.shapereader as shpreader from cartopy.mpl.geoaxes import GeoAxes from mpl_toolkits.axes_grid1 import AxesGrid from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter #make figure fig = plt.figure(figsize=(10, 10)) #add the map ax = fig.add_subplot(1, 1, 1,projection=ccrs.PlateCarree()) ax.add_feature(cfeature.STATES.with_scale('50m'),lw=0.5) ax.add_feature(cartopy.feature.OCEAN.with_scale('50m')) ax.add_feature(cartopy.feature.LAND.with_scale('50m'), edgecolor='black',lw=0.5,facecolor=[0.95,0.95,0.95]) ax.add_feature(cartopy.feature.LAKES.with_scale('50m'), edgecolor='black') ax.add_feature(cartopy.feature.RIVERS.with_scale('50m')) if (self.corners is not None) and box: ax.plot([corners[0],corners[0],corners[1],corners[1],corners[0]],[corners[2],corners[3],corners[3],corners[2],corners[2]],'-r',lw=3) ax.plot(center_lon,center_lat,'w*',ms=16,zorder=7) if z is None: ax.scatter(self.xrds.lons,self.xrds.lats,zorder=5) else: pm = ax.scatter(self.xrds.lons,self.xrds.lats,c=z,cmap=cmap,s=25,vmin=vmin,vmax=vmax,zorder=5) cbar = plt.colorbar(pm,ax=ax,shrink=0.5) cbar.set_label(z.name + ', [' + z.units + ']') ax.plot(self.xrds.lons,self.xrds.lats,'o',fillstyle='none',color='k',markeredgewidth=0.1,ms=4,zorder=6) if (self.corners is not None) and (extent is None): #for some reason set_extent crashes the session on colab. # ax.set_extent(self.corners) ax.set_xlim([self.corners[0],self.corners[1]]) ax.set_ylim([self.corners[2],self.corners[3]]) ax.set_xticks(np.arange(self.corners[0], self.corners[1], 1), crs=ccrs.PlateCarree()) ax.set_yticks(np.linspace(self.corners[2], self.corners[3], 5), crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) elif (self.corners is not None) and (extent is not None): #for some reason set_extent crashes the session on colab. # ax.set_extent(extent) ax.set_xlim([extent[0],extent[1]]) ax.set_ylim([extent[2],extent[3]]) ax.set_xticks(np.linspace(extent[0], extent[1], 5), crs=ccrs.PlateCarree()) ax.set_yticks(np.linspace(extent[2], extent[3], 5), crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) elif (self.corners is None) and (extent is not None): #for some reason set_extent crashes the session on colab. # ax.set_extent(extent) ax.set_xlim([extent[0],extent[1]]) ax.set_ylim([extent[2],extent[3]]) ax.set_xticks(np.linspace(extent[0], extent[1], 5), crs=ccrs.PlateCarree()) ax.set_yticks(np.linspace(extent[2], extent[3], 5), crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) self.ax = ax
def plot_map(cl=0.0, lat=None, lon=None, profile=None, p_direct=True, geology=False, states=False): """plot a map""" ax = plt.gca() if lat and lon: ax.set_extent((lon[0], lon[1], lat[0], lat[1])) else: ax.set_global() ax.frameon = True ax.outline_patch.set_linewidth(0.75) # Set gridlines. NO LABELS HERE, there is a bug in the gridlines # function around 180deg gl = ax.gridlines(crs=PlateCarree(central_longitude=0.0), draw_labels=False, linewidth=1, color='lightgray', alpha=0.5, linestyle='-', zorder=-1.5) gl.top_labels = False gl.left_labels = False gl.xlines = True # Add Coastline ax.add_feature(cartopy.feature.LAND, zorder=-2, edgecolor='black', linewidth=0.5, facecolor=(0.9, 0.9, 0.9)) # Add the biggest waterbodies ax.add_feature(cartopy.feature.NaturalEarthFeature('physical', 'lakes', '110m'), zorder=-2, edgecolor='black', linewidth=0.5, facecolor='w') # ax.add_feature(cartopy.feature.RIVERS, zorder=-2, edgecolor='black', # linewidth=0.5, facecolor=(0.9, 0.9, 0.9)) if lat and lon: # dy = np.floor((lat[1] - lat[0])/6) dx = np.floor((lat[1] - lat[0]) / 6) xt = np.arange(lon[0], lon[1], dx) yt = np.arange(lat[0], lat[1], dx) else: xt = np.linspace(-180, 180, 13) yt = np.linspace(-90, 90, 13) ax.set_xticks(xt, crs=ccrs.PlateCarree()) ax.set_yticks(yt, crs=ccrs.PlateCarree()) ax.xaxis.set_major_formatter(LongitudeFormatter()) ax.yaxis.set_major_formatter(LatitudeFormatter()) # ax.set_xticks(xt, crs=ccrs.Robinson()) # ax.set_yticks(yt, crs=ccrs.Robinson()) # ax.xaxis.set_major_formatter(LongitudeFormatter()) # ax.yaxis.set_major_formatter(LatitudeFormatter()) if geology: ax.add_wms(wms='https://mrdata.usgs.gov/services/worldgeol?', layers=['geology'], zorder=-2) if states: ax.add_feature(feature=cartopy.feature.STATES, linewidth=0.25, zorder=-2) if profile: if type(profile) == tuple: if p_direct: plt.plot((profile[0], profile[1]), (profile[2], profile[3]), color='blue', linewidth=1.5, transform=PlateCarree(), label='profile 1') else: p = profile ax.add_patch( matplotlib.patches.Rectangle(xy=(p[0], p[2]), height=p[3] - p[2], width=p[1] - p[0], alpha=.2, facecolor='blue')) else: # colorlist if p_direct: for ii, p in enumerate(profile): plt.plot((p[0], p[1]), (p[2], p[3]), linewidth=1.5, transform=PlateCarree(), label='profile ' + str(ii + 1)) else: cl = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'grey', 'tab:purple'] for ii, p in enumerate(profile): ax.add_patch( matplotlib.patches.Rectangle(xy=(p[0], p[2]), height=p[3] - p[2], width=p[1] - p[0], alpha=.2, label=ii, facecolor=cl[ii])) # ax.legend() return ax
def PlotComposites(model_m, lat_model, lon_model, observ_m, lat_observ, lon_observ, title, filename): proj = ccrs.Stereographic(central_longitude=-60, centra_latitude=-90) fig = plt.figure(1, (10, 6.7), 300) ax = plt.subplot(2, 1, 1, projection=proj) clevs = np.arange(-60, 70, 10) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 0], crs=ccrs.PlateCarree()) gl = ax.gridlines(draw_labels=False, xlocs=None, ylocs=None) gl.n_steps = 90 t_value = stats.t.ppf(1 - 0.025, observ_m['df']) M = np.ma.array(observ_m['var'], mask=np.abs(observ_m['mask']) < t_value) im = ax.contourf(lon_observ, lat_observ, M, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=70) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('ERA Interim', fontsize=10) ax = plt.subplot(2, 1, 2, projection=proj) ax.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) gl = ax.gridlines(draw_labels=False, xlocs=None, ylocs=None) gl.n_steps = 90 t_value = stats.t.ppf(1 - 0.025, model_m['df']) M = np.ma.array(model_m['var'], mask=np.abs(model_m['mask']) < t_value) im = ax.contourf(lon_model, lat_model, M, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.add_feature(cartopy.feature.COASTLINE) ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('ECMWF S4', fontsize=10) plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def PlotComposites(var_pos, var_neg, lat, lon, title, filename): proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) ax = plt.subplot(2, 1, 1, projection=proj) clevs = np.arange(-60, 70, 10) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var_pos, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('+NINIO3.4 YEARS') ax1 = plt.subplot(2, 1, 2, projection=proj) barra = plt.cm.RdBu_r ax1.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax1.contourf(lon, lat, var_neg, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax1.coastlines() ax1.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) #countries ax1.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax1.xaxis.set_major_formatter(lon_formatter) ax1.yaxis.set_major_formatter(lat_formatter) plt.title('-NINIO3.4 YEARS') plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def __init__(self, axes, crs, draw_labels=False, xlocator=None, ylocator=None, collection_kwargs=None, xformatter=None, yformatter=None, dms=False, x_inline=None, y_inline=None, auto_inline=True): """ Object used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines` to add gridlines and tick labels to a map. Parameters ---------- axes The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on. crs The :class:`cartopy.crs.CRS` defining the coordinate system that the gridlines are drawn in. draw_labels: optional Toggle whether to draw labels. For finer control, attributes of :class:`Gridliner` may be modified individually. Defaults to False. xlocator: optional A :class:`matplotlib.ticker.Locator` instance which will be used to determine the locations of the gridlines in the x-coordinate of the given CRS. Defaults to None, which implies automatic locating of the gridlines. ylocator: optional A :class:`matplotlib.ticker.Locator` instance which will be used to determine the locations of the gridlines in the y-coordinate of the given CRS. Defaults to None, which implies automatic locating of the gridlines. xformatter: optional A :class:`matplotlib.ticker.Formatter` instance to format labels for x-coordinate gridlines. It defaults to None, which implies the use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated with the ``dms`` argument, if the crs is of :class:`~cartopy.crs.PlateCarree` type. yformatter: optional A :class:`matplotlib.ticker.Formatter` instance to format labels for y-coordinate gridlines. It defaults to None, which implies the use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated with the ``dms`` argument, if the crs is of :class:`~cartopy.crs.PlateCarree` type. collection_kwargs: optional Dictionary controlling line properties, passed to :class:`matplotlib.collections.Collection`. Defaults to None. dms: bool When default locators and formatters are used, ticks are able to stop on minutes and seconds if minutes is set to True, and not fraction of degrees. x_inline: optional Toggle whether the x labels drawn should be inline. y_inline: optional Toggle whether the y labels drawn should be inline. auto_inline: optional Set x_inline and y_inline automatically based on projection. Notes ----- The "x" and "y" labels for locators and formatters do not necessarily correspond to X and Y, but to the first and second coordinates of the specified CRS. For the common case of PlateCarree gridlines, these correspond to longitudes and latitudes. Depending on the projection used for the map, meridians and parallels can cross both the X axis and the Y axis. """ self.axes = axes #: The :class:`~matplotlib.ticker.Locator` to use for the x #: gridlines and labels. if xlocator is not None: if not isinstance(xlocator, mticker.Locator): xlocator = mticker.FixedLocator(xlocator) self.xlocator = xlocator elif isinstance(crs, cartopy.crs.PlateCarree): self.xlocator = LongitudeLocator(dms=dms) else: self.xlocator = classic_locator #: The :class:`~matplotlib.ticker.Locator` to use for the y #: gridlines and labels. if ylocator is not None: if not isinstance(ylocator, mticker.Locator): ylocator = mticker.FixedLocator(ylocator) self.ylocator = ylocator elif isinstance(crs, cartopy.crs.PlateCarree): self.ylocator = LatitudeLocator(dms=dms) else: self.ylocator = classic_locator if xformatter is None: if isinstance(crs, cartopy.crs.PlateCarree): xformatter = LongitudeFormatter(dms=dms) else: xformatter = classic_formatter() #: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels. self.xformatter = xformatter if yformatter is None: if isinstance(crs, cartopy.crs.PlateCarree): yformatter = LatitudeFormatter(dms=dms) else: yformatter = classic_formatter() #: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels. self.yformatter = yformatter #: Whether to draw labels on the top of the map. self.top_labels = draw_labels #: Whether to draw labels on the bottom of the map. self.bottom_labels = draw_labels #: Whether to draw labels on the left hand side of the map. self.left_labels = draw_labels #: Whether to draw labels on the right hand side of the map. self.right_labels = draw_labels if auto_inline: if isinstance(self.axes.projection, _X_INLINE_PROJS): self.x_inline = True self.y_inline = False elif isinstance(self.axes.projection, _POLAR_PROJS): self.x_inline = False self.y_inline = True else: self.x_inline = False self.y_inline = False # overwrite auto_inline if necessary if x_inline is not None: #: Whether to draw x labels inline self.x_inline = x_inline elif not auto_inline: self.x_inline = False if y_inline is not None: #: Whether to draw y labels inline self.y_inline = y_inline elif not auto_inline: self.y_inline = False #: Whether to draw the x gridlines. self.xlines = True #: Whether to draw the y gridlines. self.ylines = True #: A dictionary passed through to ``ax.text`` on x label creation #: for styling of the text labels. self.xlabel_style = {} #: A dictionary passed through to ``ax.text`` on y label creation #: for styling of the text labels. self.ylabel_style = {} #: The padding from the map edge to the x labels in points. self.xpadding = 5 #: The padding from the map edge to the y labels in points. self.ypadding = 5 #: Allow the rotation of labels. self.rotate_labels = True # Current transform self.crs = crs # if the user specifies tick labels at this point, check if they can # be drawn. The same check will take place at draw time in case # public attributes are changed after instantiation. if draw_labels and not (x_inline or y_inline or auto_inline): self._assert_can_draw_ticks() #: The number of interpolation points which are used to draw the #: gridlines. self.n_steps = 100 #: A dictionary passed through to #: ``matplotlib.collections.LineCollection`` on grid line creation. self.collection_kwargs = collection_kwargs #: The x gridlines which were created at draw time. self.xline_artists = [] #: The y gridlines which were created at draw time. self.yline_artists = [] # Plotted status self._plotted = False # Check visibility of labels at each draw event # (or once drawn, only at resize event ?) self.axes.figure.canvas.mpl_connect('draw_event', self._draw_event)
def PlotCompositesDivPlumbPV(var_pos, var_neg, u_pos, u_neg, v_pos, v_neg, lat, lon, title, filename): proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) ax = plt.subplot(2, 1, 1, projection=proj) clevs = np.arange(-1.2, 1.6, 0.8) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 0], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var_pos / 10, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-1.2, vmax=1.2) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) M = np.sqrt(np.add(np.power(u_pos, 2), np.power(v_pos, 2))) < 0.3 #mask array u_mask = ma.array(u_pos, mask=M) v_mask = ma.array(v_pos, mask=M) ax.quiver( lon[0:-1:6], lat[0:-1:6], u_mask[0:-1:6, 0:-1:6], v_mask[0:-1:6, 0:-1:6], transform=ccrs.PlateCarree(), angles='xy' ) #, headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('Strong PV YEARS') ax1 = plt.subplot(2, 1, 2, projection=proj) ax1.set_extent([0, 359, -90, 0], crs=ccrs.PlateCarree()) im = ax1.contourf(lon, lat, var_neg / 10, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-1.2, vmax=1.2) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) M = np.sqrt(np.add(np.power(u_neg, 2), np.power(v_neg, 2))) < 0.3 #mask array u_mask = ma.array(u_neg, mask=M) v_mask = ma.array(v_neg, mask=M) ax1.quiver( lon[0:-1:6], lat[0:-1:6], u_mask[0:-1:6, 0:-1:6], v_mask[0:-1:6, 0:-1:6], transform=ccrs.PlateCarree(), angles='xy' ) #, headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) ax1.coastlines() ax1.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) #countries ax1.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax1.xaxis.set_major_formatter(lon_formatter) ax1.yaxis.set_major_formatter(lat_formatter) plt.title('Weak PV YEARS') plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
cmap.set_under('white') bounds = [0.1, 0.5, 1, 2, 3, 4, 5, 6, 8, 10, 20, 40] norm = mpl.colors.BoundaryNorm(bounds, cmap.N) im = ax.imshow(crain, transform=PlateCarree, origin='upper', extent=[70, 139.95, 15, 59.95], cmap=cmap, norm=norm, aspect=1.2) cb = fig.colorbar(im, ax=ax, extend="both", extendrect=True, ticks=bounds, extendfrac="auto", pad=0.01, shrink=0.8, aspect=40, fraction=0.01) cb.set_label("mm") ax.set_xlim((72, 135)) ax.set_ylim((18, 55)) ax.set_xticks(list(range(75, 136, 5)), PlateCarree) ax.set_yticks(list(range(20, 56, 5)), PlateCarree) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) ax.set_title("中国自动站与CMORPH降水产品融合的逐小时降水量", fontproperties=font, fontsize=23) plt.text(1, -0.07, "公众号 碎积云", fontproperties=font, transform=ax.transAxes, horizontalalignment="right", verticalalignment="top", fontsize=14) plt.text(0.5, 0.98, "2018-08-17 07:00(GMT)", fontproperties=font, transform=ax.transAxes, horizontalalignment="center", verticalalignment="top", fontsize=15) southsea = plt.imread(r"..\data\map\南海诸岛插图.tif") y, x = southsea.shape[:2] ax.imshow(southsea, origin='upper', extent=[135-10, 135, 18, 18+10/x*y], aspect=1.2) plt.show() plt.savefig(r"..\data\SURF_CLI_CHN_MERGE_CMP_PRE_HOUR_GRID_0.10\demo.png")
extend = 'both', cmap = cmocean.cm.balance, projection=ccrs.PlateCarree()) #add colorbar cb1 = fig.colorbar(contf1, ticks = np.linspace(-100,100,11), format = '%.0f', orientation = 'horizontal',fraction=0.08, pad=0.15) #set colorbar format cb1.set_label('cm/year', fontsize = 16) cb1.ax.tick_params(labelsize=16) #set ax1 label's and tick's format ax1.set_xticks([ -180, -120, -60,0, 60, 120, 180,], crs=ccrs.PlateCarree()) ax1.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree()) ax1.tick_params(axis='both', labelsize=20) ax1.xaxis.set_major_formatter(LongitudeFormatter()) ax1.yaxis.set_major_formatter(LatitudeFormatter()) ##plot ax2, temporal change of zonal average evaporation ax2 = fig.add_subplot(grid[0,2]) t = -time_lgm[0] ax2.plot(prect_zonal[0,:], lat, linewidth=3.0, color = 'b', linestyle = '--', label='%.2f ky BP' %t) ax2.plot(prect_1850_1980_zonal, lat, linewidth = 2.0, color = 'r', label = '1850-1980 AD') #set ax2 format ax2.set_ylabel('°N',fontsize = 16) ax2.tick_params(labelsize=16) ax2.set_xlabel("cm/year",fontsize = 16) ax2.set_xlim([0,240]) ax2.legend(fontsize = 12) #animate the plot with temporal change def animate(i):
cbar.outline.set_linewidth(0.5) # Sets X axis characteristics xticks = np.arange(-180.0, 25.0, 20.0) ax.set_xticks(xticks, crs=MapProj) ax.set_xticklabels(xticks, fontsize=5.5, color='black') lon_formatter = LongitudeFormatter(number_format='.0f', degree_symbol='°', dateline_direction_label=True) ax.xaxis.set_major_formatter(lon_formatter) # Sets Y axis characteristics yticks = np.arange(90.0, -95.0, -15.0) ax.set_yticks(yticks, crs=MapProj) ax.set_yticklabels(yticks, fontsize=5.5, color='black') lat_formatter = LatitudeFormatter(number_format='.0f', degree_symbol='°') ax.yaxis.set_major_formatter(lat_formatter) # Sets grid characteristics ax.tick_params(left=True, bottom=True, labelleft=True, labelbottom=True, length=0.0, width=0.05) ax.gridlines(xlocs=xticks, ylocs=yticks, color='gray', alpha=0.6, draw_labels=False, linewidth=0.25,
def test_LatitudeFormatter_bad_projection(): formatter = LatitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) match = r'This formatter cannot be used with non-rectangular projections\.' with pytest.raises(TypeError, match=match): formatter(0)
def plot_panel(n, fig, var, clevels, cmap, title, parameters, stats=None): mon = var.getTime() lat = var.getLatitude() var = np.transpose(var) # Contour levels levels = None norm = None if len(clevels) > 0: levels = [-1.0e8] + clevels + [1.0e8] norm = colors.BoundaryNorm(boundaries=levels, ncolors=256) # Contour plot ax = fig.add_axes(panel[n]) cmap = get_colormap(cmap, parameters) # p1 = ax.contourf( p1 = ax.pcolor( mon, lat, var, norm=norm, cmap=cmap, edgecolors="face", shading="auto", ) if title[0] is not None: ax.set_title(title[0], loc="left", fontdict=plotSideTitle) if title[1] is not None: ax.set_title(title[1], fontdict=plotTitle) if title[2] is not None: ax.set_title(title[2], loc="right", fontdict=plotSideTitle) mon_xticks = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"] plt.xticks(mon, mon_xticks) lat_formatter = LatitudeFormatter() ax.yaxis.set_major_formatter(lat_formatter) ax.tick_params(labelsize=8.0, direction="out", width=1) ax.xaxis.set_ticks_position("bottom") ax.yaxis.set_ticks_position("left") # Color bar cbax = fig.add_axes( (panel[n][0] + 0.6635, panel[n][1] + 0.0215, 0.0326, 0.1792)) cbar = fig.colorbar(p1, cax=cbax, extend="both") w, h = get_ax_size(fig, cbax) if levels is None: cbar.ax.tick_params(labelsize=9.0, length=0) else: maxval = np.amax(np.absolute(levels[1:-1])) if maxval < 10.0: fmt = "%5.2f" pad = 25 elif maxval < 100.0: fmt = "%5.1f" pad = 25 else: fmt = "%6.1f" pad = 30 cbar.set_ticks(levels[1:-1]) labels = [fmt % level for level in levels[1:-1]] if all(x[-2:] == ".0" for x in labels): labels = [x[:-2] for x in labels] pad = pad - 5 cbar.ax.set_yticklabels(labels, ha="right") cbar.ax.tick_params(labelsize=9.0, pad=pad, length=0)
def test_LatitudeFormatter_bad_projection(): formatter = LatitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) message = 'This formatter cannot be used with non-rectangular projections.' with assert_raises_regexp(TypeError, message): formatter(0)
def test_LatitudeFormatter_bad_axes(): formatter = LatitudeFormatter() formatter.axis = Mock(axes=Mock(Axes, projection=ccrs.PlateCarree())) message = 'This formatter can only be used with cartopy axes.' with pytest.raises(TypeError, message=message): formatter(0)
def plot_basin(gauge_id, dlat=0.05, dlon=0.1, tile_level=12): """ Plots location of gauge and surrounding territory. Args: gauge_id(int): The ID of the gauge to display dlat: Meridional extent of the map in degrees. dlon: Equatorial extent of the map in degrees. tile_level: The resolution level to use for the terrain in the background. """ if not gauge_id in gauge_ids: other = gauge_ids[np.argmin(np.abs(int(gauge_id) - gauge_ids))] raise ValueError("Gauge ID {} is not available from this dataset. The " "closest ID available is {}.".format(gauge_id, other)) try: from cartopy.io.img_tiles import Stamen from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter import cartopy.crs as ccrs lat = float(gauge_information.loc[gauge_information["gauge id"] == gauge_id]["latitude"]) lon = float(gauge_information.loc[gauge_information["gauge id"] == gauge_id]["longitude"]) tiler = Stamen("terrain") mercator = tiler.crs f = plt.figure(figsize = (8, 6)) gs = GridSpec(1, 1) ax = plt.subplot(gs[0], projection=mercator) lon_min = lon - dlon lon_max = lon + dlon lat_min = lat - dlat lat_max = lat + dlat ax.set_extent([lon_min, lon_max, lat_min, lat_max]) ax.add_image(tiler, tile_level) ax.set_xlabel("Longitude") ax.set_ylabel("Latitude") lon_min_r = np.round(lon - dlon, decimals=1) lon_max_r = np.round(lon + dlon, decimals=1) lat_min_r = np.round(lat - dlat, decimals=1) lat_max_r = np.round(lat + dlat, decimals=1) xticks = np.arange(lon_min, lon_max, 0.05) yticks = np.arange(lat_min, lat_max, 0.05) ax.set_xticks(xticks, crs=ccrs.PlateCarree()) ax.set_yticks(yticks, crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) img=ax.scatter([lon], [lat], transform=ccrs.PlateCarree(), c="k", marker="x", s=50, label="Gauge location") ax.legend() except: url = "http://spfrnd.de/datasets/camels/plots/{}.png".format(gauge_id) img = plt.imread(url) plt.figure(figsize=(3,2), dpi=300) plt.imshow(img) plt.gca().set_axis_off()
def __call__(self, da, ax=None, bnds=[0, 360, -90, 90], projection_name='PlateCarree', **plt_kwargs): # Central longitude must be between -180 and 180 (greenwich meridian is 0) #lon_0 = (bnds[0] + bnds[1])/2 - 360 lon_0 = (bnds[0] + bnds[1]) / 2 #print('lon_0', lon_0) if projection_name == 'PlateCarree': projection = cart.crs.PlateCarree(central_longitude=lon_0) elif projection_name == 'Robinson': projection = cart.crs.Robinson(central_longitude=lon_0) else: print('Projection name must be "PlateCarree" or "Robinson".') assert set(da.dims) == set( ['face', 'j', 'i']), "da must have dimensions ['face', 'j', 'i']" if ax is None: fig, ax = plt.subplots(figsize=(12, 6)) #print(self.orig_grid.shape) #print(da.values.shape) #print(self.new_grid.shape) field = pyresample.kd_tree.resample_nearest(self.orig_grid, da.values, self.new_grid, radius_of_influence=100000, fill_value=None) vmax = plt_kwargs.pop('vmax', field.max()) vmin = plt_kwargs.pop('vmin', field.min()) m = plt.axes(projection=projection) x, y = self.new_grid_lon, self.new_grid_lat #ax= plt.gca() pardiff = 30. merdiff = 60. if np.abs(bnds[1] - bnds[0]) < 180: merdiff = 30. if np.abs(bnds[1] - bnds[0]) < 90: merdiff = 15. if np.abs(bnds[3] - bnds[2]) < 90: pardiff = 15. par = np.arange(-90., 90. + pardiff, pardiff) mer = np.arange(-180., 180. + merdiff, merdiff) ax = plt.gca() ax.set_xticks(mer, crs=cart.crs.PlateCarree()) ax.set_yticks(par, crs=cart.crs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) ax.get_yaxis().set_tick_params(direction='out') ax.get_xaxis().set_tick_params(direction='out') ax.set_extent((bnds[0], bnds[1], bnds[2], bnds[3]), crs=cart.crs.PlateCarree()) # Find index where data is splitted for mapping split_lon_idx = round(x.shape[1] / (360 / (lon_0 if lon_0 > 0 else lon_0 + 360))) p = m.pcolormesh(x[:, :split_lon_idx], y[:, :split_lon_idx], field[:, :split_lon_idx], vmax=vmax, vmin=vmin, transform=cart.crs.PlateCarree(), zorder=1, **plt_kwargs) p = m.pcolormesh(x[:, split_lon_idx:], y[:, split_lon_idx:], field[:, split_lon_idx:], vmax=vmax, vmin=vmin, transform=cart.crs.PlateCarree(), zorder=2, **plt_kwargs) gl = ax.gridlines(crs=cart.crs.PlateCarree(), linewidth=0.5, color='black', alpha=0.6, linestyle='-.', zorder=10) gl.xlocator = mticker.FixedLocator(mer) gl.ylocator = mticker.FixedLocator(par) #ax.set_facecolor('grey') #m.add_feature(cart.feature.LAND, facecolor='0.5', zorder=3) #m.add_feature(cart.feature.COASTLINE,linewidth=0.5, zorder=15) label = '' if da.name is not None: label = da.name if 'units' in da.attrs: label += ' [%s]' % da.attrs['units'] orient = 'vertical' if np.abs(bnds[1] - bnds[0]) > (np.abs(bnds[3] - bnds[2]) - 10): orient = 'horizontal' cb = plt.colorbar(p, fraction=0.07, pad=0.1, label=label, orientation=orient) return m, ax
def draw_basemap(ax, extent=None, xticks=None, yticks=None, grid=False): """ Draws a basemap on which to plot data. Map features include continents and country borders. Option to set lat/lon tickmarks and draw gridlines. Parameters ---------- ax : plot Axes on which to draw the basemap extent : float Set map extent to [lonmin, lonmax, latmin, latmax] Default: None (uses global extent) grid : bool Whether to draw grid lines. Default: False xticks : float array of xtick locations (longitude tick marks) yticks : float array of ytick locations (latitude tick marks) Returns ------- ax : plot Axes with Basemap Notes ----- - Grayscale colors can be set using 0 (black) to 1 (white) - Alpha sets transparency (0 is transparent, 1 is solid) Author ------ Tessa Montini, [email protected] """ # Use map projection (CRS) of the given Axes mapcrs = ax.projection ## Map Extent # If no extent is given, use global extent if extent is None: ax.set_global() # If extent is given, set map extent to lat/lon bounding box else: ax.set_extent(extent, crs=mapcrs) # Add map features (continents and country borders) ax.add_feature(cfeature.LAND, facecolor='0.9') ax.add_feature(cfeature.BORDERS, edgecolor='0.4', linewidth=0.8) ax.add_feature(cfeature.COASTLINE, edgecolor='0.4', linewidth=0.8) ## Tickmarks/Labels # Set xticks if requested if xticks is not None: ax.set_xticks(xticks, crs=mapcrs) lon_formatter = LongitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) # Set yticks if requested if yticks is not None: ax.set_yticks(yticks, crs=mapcrs) lat_formatter = LatitudeFormatter() ax.yaxis.set_major_formatter(lat_formatter) # apply tick parameters ax.tick_params(direction='out', labelsize=8.5, length=4, pad=2, color='black') ## Gridlines # Draw gridlines if requested if (grid == True): ax.grid(color='k', alpha=0.5, linewidth=0.5, linestyle='--') return ax
def test_LatitudeFormatter_bad_axes(): formatter = LatitudeFormatter() formatter.axis = Mock(axes=Mock(Axes, projection=ccrs.PlateCarree())) message = 'This formatter can only be used with cartopy axes.' with assert_raises_regexp(TypeError, message): formatter(0)
def map(self): import matplotlib.pyplot as plt import seaborn as sns import cartopy.crs as ccrs from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter print("Plotting global distribution of samples...") dlon, dlat = 2.5, 1.9 npoints = len(self._df) df_map = self._df.copy() def rand_fact(npoints, width): """ Rescale a number from [0, 1) to [-width, width) """ points = 2. * np.random.random(npoints) - 1. points *= width return points l1 = df_map['lon'].copy() l2 = df_map['lat'].copy() df_map['lon'] = df_map['lon'] + rand_fact(npoints, dlon / 2.) df_map['lat'] = df_map['lat'] + rand_fact(npoints, dlat / 2.) lon, lat = df_map.lon, df_map.lat # Correct lon: # 1) some values may be < 0 or > 360, map these into [0, 360] lon[lon < 0] = lon[lon < 0] + 360. lon[lon > 360] = lon[lon > 360] - 360. # 2) map from [0, 360] -> [-180, 180] lon -= 180. df_map['lon'] = lon[:] proj = ccrs.PlateCarree() cmap = sns.light_palette("navy", 12, as_cmap=True) fig, ax = plt.subplots(1, 1, figsize=(10, 5), subplot_kw=dict(projection=proj)) cax = fig.add_axes([0, 0, 0.1, 0.1]) fig.subplots_adjust(hspace=0, wspace=0, top=0.925, left=0.1) hb = ax.hexbin(lon, lat, gridsize=(50, 15), bins='log', transform=proj, cmap=cmap) # This block of code helps correctly size and place the colorbar def resize_colorbar(event): plt.draw() posn = ax.get_position() cax.set_position( [posn.x0 + posn.width + 0.01, posn.y0, 0.04, posn.height]) fig.canvas.mpl_connect('resize_event', resize_colorbar) ax.coastlines() ax.set_global() ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=proj) ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=proj) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.colorbar(hb, cax, ax) plt.show()