def plot_regions(regions, ptype='nh', colors='k', latlim=None, drawgrid=False): """ plot multiple region boundaries on one map regions: tuple of region names default color = black colors can be a tuple of color specifications. index will wrap if not enough """ dummy = con.get_t63landmask() lat = con.get_t63lat() lon = con.get_t63lon() lons,lats = np.meshgrid(lon,lat) dummy = dummy*np.nan plt.figure() bm,pc = kemmap(dummy,lat,lon,ptype=ptype,latlim=latlim,suppcb=1, drawgrid=drawgrid, lmask=True) for ii,reg in enumerate(regions): if len(colors)==1: clr=colors else: if ii==len(colors): ii=0 # wrap index clr=colors[ii] add_regionpolym(reg,bm, ec=clr)
def plot_region(regname,ptype='nh',axis=None,latlim=None,limsdict=None): """ plot_region(regname,ptype='nh',axis=None,latlim=None,limsdict=None): Given a region name, plot it for reference. latlims is unused right now if passing limsdict (to override regname), set regname='other' """ if regname=='other': reglims=limsdict else: reglims = con.get_regionlims(regname) latlims = reglims['latlims'] lonlims = reglims['lonlims'] dummy = con.get_t63landmask() lat = con.get_t63lat() lon = con.get_t63lon() lons,lats = np.meshgrid(lon,lat) reglatsbool = np.logical_and(lat>latlims[0],lat<latlims[1]) reglonsbool = np.logical_and(lon>lonlims[0],lon<lonlims[1]) # mask everything but the region of interest regmask = np.logical_or( np.logical_or(lats<latlims[0],lats>latlims[1]), np.logical_or(lons<lonlims[0],lons>lonlims[1])) dummym = ma.masked_where(regmask,dummy) plt.figure() kemmap(dummym,lat,lon,ptype=ptype,axis=axis,latlim=latlim,suppcb=1, cmin=-11,cmax=2,cmap='blue2blue_w10',drawgrid=True)
def calc_areaweight_mean_ds(ds,dim=None, mask=None, model='CanESM2'): """ Calculates area-weighted mean of the input Dataset (or DataArray?? test) If the input ds is a subregion, this should still work. (tested with polcap60) mask: ['land' | 'ocean'] (mask='land' means mask OUT land) Lakes are not included in land or ocean. @@this is hard-coded to CanESM2. @ return area-weighted values in a Dataset (or DataArray?? test) """ aweights = get_areaweights_ds(ds) if mask!=None: import constants as con if model=='CanESM2': lmask = xr.DataArray(con.get_t63landmask()[:,:-1], dims=('lat','lon'), coords=[ds.lat,ds.lon],name='lmask') #print lmask else: raise Exception('No landmask defined for model ' + model) if mask=='land': mval = -1; elif mask=='ocean': mval=0 #awgtsub = aweights.values #awgtsub[lmask!=mval] = np.nan #awgtsub = awgtsub / np.float(np.nansum(awgtsub))# normalize weights #aweights.values = awgtsub #print ds.where(lmask!=mval).values.shape #ds.where(lmask!=mval) #dssub = ds.values #dssub[lmask!=mval] = np.nan #ds.values = dssub if dim!=None: if mask!=None: aw=aweights.where(lmask!=mval) / aweights.where(lmask!=mval).sum() return (aw * ds.where(lmask!=mval)).sum(dim=dim) else: return (aweights * ds).sum(dim=dim) else: if mask!=None: aw=aweights.where(lmask!=mval) / aweights.where(lmask!=mval).sum() return (aw * ds.where(lmask!=mval)).sum() else: return (aweights * ds).sum()
def plot_allregions(ptype='nh'): """ plot_allregions(ptype='nh'): plot all defined regions """ regdict = con.get_regiondict() nreg = len(regdict) rem = np.mod(nreg,2) rows = 2 if rem==0: cols = nreg/rows else: cols = nreg/rows + rem # rem will always be 1 if dividing by 2 if cols>8: rows = 3 cols = nreg/rows + np.mod(nreg,rows)/2 print 'nrows: ' + str(rows) + ' ncols: ' + str(cols) # @@@ lat = con.get_t63lat() lon = con.get_t63lon() fig,spax = plt.subplots(rows,cols) fig.set_size_inches(cols*2,rows*3) for aii,ax in enumerate(spax.flat): dummy = con.get_t63landmask() # dummy data regkey = regdict.keys()[aii] limsdict = regdict[regkey] # mask the dummy data dummym,dmask = cutl.mask_region(dummy,lat,lon,regkey,limsdict=limsdict) kemmap(dummym,lat,lon,ptype=ptype,axis=ax,suppcb=1,cmin=-11,cmax=2,cmap='blue2blue_w10') ax.set_title(regkey) ax.set_xlabel(str(limsdict['latlims']) + ',' +str(limsdict['lonlims']) ) if aii==nreg-1: break # get out of loop if done with regions
cansicp,cansicpstd = cutl.climatologize(cnc.getNCvar(fcansicp,'GT')) hurrsicc = cnc.getNCvar(fhurrsic,'SST')+273 #hurrsicc.resize(hadsicc.shape) # can't resize like this. ?? #np.append(hurrsicc,hurrsicc[:,:,0])#,axis=2) # could not get append to work #hurrsicc[:,:,len(lon)-1] = hurrsicc[:,:,0] # add a wraparound. nope. #hurrsicc = np.flipud(hurrsicc) # the lats are flipped compared to hadisst and nsidc hurrsicp = cnc.getNCvar(fhurrsicp,'SST')+273 #hurrsicc.resize(hadsicc.shape) # other datasets have extra lon. #hurrsicp[:,:,len(lon)-1] = hurrsicp[:,:,0] # add a wraparound #hurrsicp = np.flipud(hurrsicp) # the lats are flipped compared to hadisst and nsidc # MASK out land & inland lakes lsmask=con.get_t63landmask() lsmask = np.tile(lsmask,(12,1,1)) ## if flipmask: ## lsmask=np.flipud(lsmask) hadsicc = ma.masked_where(lsmask!=0,hadsicc) # 0 is ocean hadsicp = ma.masked_where(lsmask!=0,hadsicp) # 0 is ocean hadsicc = hadsicc[:,:,0:-1] hadsicp = hadsicp[:,:,0:-1] #hurrsicc = ma.masked_where(lsmask!=0,hurrsicc) # 0 is ocean # @@ BOGUS cansicc = ma.masked_where(lsmask!=0,cansicc) # 0 is ocean cansicp = ma.masked_where(lsmask!=0,cansicp) # 0 is ocean cansicc = cansicc[:,:,0:-1] cansicp = cansicp[:,:,0:-1] hadsicd = hadsicp-hadsicc
axis=0) if sia==1: fldc = cutl.calc_seaicearea(fldc,lat,lon) fldp = cutl.calc_seaicearea(fldp,lat,lon) # Prepare the data here: @@ # @@ from hists script: areas = cutl.calc_cellareas(lat,lon,repeat=fldc.shape) areas = areas[:,lat>latlim,:] fldcorig=copy.copy(fldc) fldporig=copy.copy(fldp) fldc = fldc[:,lat>latlim,:] fldp = fldp[:,lat>latlim,:] if maskland: lmask = con.get_t63landmask(repeat=fldc.shape) areas = ma.masked_where(lmask[:,lat>latlim,:]==-1,areas) fldc = ma.masked_where(lmask[:,lat>latlim,:]==-1,fldc) fldp = ma.masked_where(lmask[:,lat>latlim,:]==-1,fldp) mtype='ocn' elif maskocean: lmask = con.get_t63landmask(repeat=fldc.shape) areas = ma.masked_where(lmask[:,lat>latlim,:]!=-1,areas) fldc = ma.masked_where(lmask[:,lat>latlim,:]!=-1,fldc) fldp = ma.masked_where(lmask[:,lat>latlim,:]!=-1,fldp) mtype='lnd' totarea = np.sum(np.sum(areas,axis=2),axis=1) totarea = np.tile(totarea,(fldc.shape[1],fldc.shape[2],1)) totarea = np.transpose(totarea,(2,0,1)) weights = areas/totarea
def kemmap(fld, lat, lon,title='',units='',cmap='blue2red_w20',ptype='sq', cmin='',cmax='',axis=None, suppcb=0,lmask=0,flipmask=0,latlim=None,drawgrid=False, round=True,lcol='0.7',coastres='c',coastwidth=1,area_thresh=10000,panellab=None): """ returns bm,pc (Basemap,Pcolor handle) """ if cmap =='' or cmap==None: cmap='blue2red_w20' incmap = plt.cm.get_cmap(cmap) # default Basemap dictionary if ptype == 'sq': mapparams = dict(projection='robin',lon_0=180,lat_0=0, resolution=coastres,area_thresh=area_thresh) elif ptype == 'sqshift': mapparams = dict(projection='robin',lon_0=0,lat_0=0, resolution=coastres,area_thresh=area_thresh) elif ptype == 'nh' or ptype=='nheur' or ptype=='nhkug': if ptype=='nheur': lon0 = 90. elif ptype=='nhkug': lon0 = 180. else: lon0=0. if latlim != None: # try 'round=True' !@@@ mapparams = dict(projection='npstere',boundinglat=latlim,lon_0=lon0, resolution=coastres,area_thresh=area_thresh) if round==True: mapparams['round'] = True else: # try mill, hammer, merc mapparams = dict(projection='ortho',lon_0=lon0,lat_0=89.5,\ resolution=coastres,area_thresh=area_thresh) #llcrnrlon='-180',llcrnrlat='45',urcrnrlon='180',urcrnrlat='90' # I thought the above corner limits would work to zoom on NH but I'm getting # AttributeError: 'Basemap' object has no attribute '_height' # 5/12/14 -- don't know why. same goes for lat_0=0. # 10/13/2015: changed lat_0 to 89.5 from 90. b/c .eps figure file wouldn't save elif ptype == 'sh': if latlim != None: # try 'round=True' !@@@ mapparams = dict(projection='spstere',boundinglat=latlim,lon_0=0, resolution=coastres,area_thresh=area_thresh) if round==True: mapparams['round'] = True else: mapparams = dict(projection='ortho',lon_0=0.,lat_0=-89.5, resolution=coastres,area_thresh=area_thresh) # same error if add: llcrnrlon='-180',llcrnrlat='-90',urcrnrlon='180',urcrnrlat='-45' elif ptype == 'eastere': # Eurasia stere projection #mapparams = dict(width=2500000,height=2700000,resolution='i',projection='laea',\ # lat_ts=62.5,lat_0=62.5,lon_0=77.0) mapparams = dict(llcrnrlon=40.,llcrnrlat=10.,urcrnrlon=160.,urcrnrlat=50., resolution=coastres,area_thresh=area_thresh,projection='stere',lat_0=45.,lon_0=80.) #mapparams = dict(width=3000000,height=3000000,resolution='c',projection='laea',\ # lat_0=55.,lon_0=80.)# can't get width/height big enough -- errors elif ptype == 'eabksstere': # Eurasia + Barents Kara attempt mapparams = dict(llcrnrlon=40.,llcrnrlat=10.,urcrnrlon=175.,urcrnrlat=60., resolution=coastres,area_thresh=area_thresh,projection='stere',lat_0=45.,lon_0=80.) elif ptype == 'ealamb': # Lambert azimuthal equal-area mapparams = dict(llcrnrlon=40.,llcrnrlat=10.,urcrnrlon=160.,urcrnrlat=50., resolution=coastres,area_thresh=area_thresh,projection='laea',lat_0=45.,lon_0=80.) elif ptype == 'eabkslamb': # Lambert azimuthal equal-area mapparams = dict(llcrnrlon=40.,llcrnrlat=10.,urcrnrlon=175.,urcrnrlat=60., resolution=coastres,area_thresh=area_thresh,projection='laea',lat_0=45.,lon_0=80.) elif ptype == 'nastere': # North America stere projection mapparams = dict(llcrnrlon=220.,llcrnrlat=20.,urcrnrlon=320.,urcrnrlat=50., resolution=coastres,area_thresh=area_thresh,projection='stere',lat_0=45.,lon_0=230.) else: print "Incorrect map ptype. Choose sq,nh,nheur,nhkug,sh,nastere,eastere,eabksstere,ealamb,eabkslamb" return -1 # default pcolormesh dictionary if cmin =='': #pcparams = dict(shading='gouraud',latlon=True,cmap=incmap) pcparams = dict(latlon=True,cmap=incmap) else: cmlen=float(incmap.N) # or: from __future__ import division if cmlen>200: cmlen = float(20) # ie. if using a built in colormap that is continuous, want smaller # of colors incr = (cmax-cmin) /cmlen conts = np.arange(cmin,cmax+incr,incr) #pcparams = dict(shading='gouraud',latlon=True,cmap=incmap,vmin=cmin,vmax=cmax) pcparams = dict(latlon=True,cmap=incmap,vmin=cmin,vmax=cmax) if ptype not in ('eastere','eabksstere','nastere','ealamb','eabkslamb'): pcparams['levels']=conts pcparams['extend']='both' if axis != None: # if an axis is given, add to dict for basemap mapparams['ax'] = axis if ptype in ('eastere','eabksstere','nastere','ealamb','eabkslamb'): pcparams['shading']='flat' #'gouraud' # @@ gouraud pdf files fail/crash. flat and interp are same?? """ m = Basemap(projection='ortho',lon_0=lon_0,lat_0=lat_0,resolution='l',\ llcrnrx=0.,llcrnry=0.,urcrnrx=m1.urcrnrx/2.,urcrnry=m1.urcrnry/2.) """ bm = Basemap(**mapparams) #if np.mod(lon.shape[0],2) == 0: if np.mod(len(lon),2) == 0: # add cyclic lon fld,lon = mpltk.basemap.addcyclic(fld,lon) if lmask==1: # the landmask has an extra lon already # add land mask lsmask=con.get_t63landmask() if flipmask: lsmask=np.flipud(lsmask) #@@@fld = ma.masked_where(lsmask!=0,fld) # 0 is ocean lons, lats = np.meshgrid(lon,lat) # pc = bm.pcolormesh(lons,lats,fld,**pcparams) if cmin=='': if ptype in ('eastere','eabksstere','nastere','ealamb','eabkslamb'): # for some reason these projections don't plot colors correctly so have to use pcolormesh()@@@ pc=bm.pcolormesh(lons,lats,fld,**pcparams) else: pc = bm.contourf(lons,lats,fld,20,**pcparams) # 20 auto levels else: if ptype in ('eastere','eabksstere','nastere','ealamb','eabkslamb'): pc=bm.pcolormesh(lons,lats,fld,**pcparams) else: #print '@@@@@@@@@@@ ' + str(pcparams) pc = bm.contourf(lons,lats,fld,**pcparams) if drawgrid: bm.drawparallels(np.arange(-90.,90.,20.),labels=[1,0,0,0]) bm.drawmeridians(np.arange(0.,360.,30.),labels=[0,0,0,1]) bm.drawcoastlines(color=lcol,linewidth=coastwidth) #bm.drawmapboundary(fill_color='#99ffff') if lmask: #@@@bm.drawmapboundary(fill_color='0.7') if float(lcol)>0.7: bm.drawcoastlines(color='.5',linewidth=coastwidth) else: bm.drawcoastlines(color='.3',linewidth=coastwidth) bm.fillcontinents(color=lcol) # I think drawlsmask puts the mask on the bottom #bm.drawlsmask(land_color='0.7',lsmask=con.get_t63landmask(),ax=axis) if axis!=None: axis.set_title(title,fontsize=10) if panellab!=None: axis.annotate(panellab,xy=(0.01,1.02), xycoords='axes fraction',fontsize=18,fontweight='bold') else: plt.title(title,fontsize=10) if panellab!=None: plt.annotate(panellab,xy=(0.01,1.02), xycoords='axes fraction',fontsize=18,fontweight='bold') # add colorbar. if suppcb == 0: cbar = bm.colorbar(pc,location='bottom',pad="5%") cbar.set_label(units) return bm,pc