def time_series(self,varname,x,y,times=None,depth=None,**opts): coords=opts.get('coords',self._default_coords('time_series')).split(',') if times is None: times=range(0,self.time.size) # depth or s_level: check if is float or if is negative! isDepth=False if not depth is None: if calc.isiterable(depth): depth=np.asarray(depth) if calc.isarray(depth): isDepth=np.any(depth<0) or depth.kind!='i' else: isDepth=depth<0 or np.asarray(depth).dtype.kind!='i' out=vis.Data() out.label='time_series' if not depth is None and not isDepth: out.msg=self.check_slice(varname,t=np.max(times),k=depth) else: out.msg=self.check_slice(varname,t=np.max(times)) if out.msg: return out # find nearest point: ### lon,lat,hr,mr=self.grid.vars(ruvp=self.var_at(varname)) lon,lat,hr,mr=self.grid.vars(ruvp=self.vloc(varname)) dist=(lon-x)**2+(lat-y)**2 i,j=np.where(dist==dist.min()) i,j=i[0],j[0] if not depth is None and not isDepth: arg={'s_SEARCH':depth} else: arg={} v=self.use(varname,xiSEARCH=j,etaSEARCH=i,SEARCHtime=times,**arg).T # calculate depths: ### if self.hasz(varname): if 'z' in self.vaxes(varname): h=self.grid.h[i,j] zeta=self.use('zeta',xiSEARCH=j,etaSEARCH=i,SEARCHtime=times) h=h+0*zeta #### z=rt.s_levels(h,zeta,self.s_params,rw=varname) ### z=rt.s_levels(h,zeta,self.s_params,rw=self.var_at(varname)[1]) z=rt.s_levels(h,zeta,self.s_params,rw=self.vloc(varname)[1]) z=np.squeeze(z) # depth slice: ### if isDepth and self.hasz(varname): if isDepth and 'z' in self.vaxes(varname): if v.ndim==2: # could use calc.griddata, but better use slicez cos data at # different times may be independent! if 0: from matplotlib.dates import date2num t=np.tile(date2num(self.time[times]),(v.shape[0],1)) v=calc.griddata(t,z,v,t[0],depth+np.zeros(t[0].shape), extrap=opts.get('extrap',False),norm_xy=opts.get('norm_xy',False)) # norm_xy True may be needed! # extrap also may be needed cos the 1st and last value may be masked! else: nt=len(times) land_mask=np.ones((nt,1),dtype=v.dtype) # needed for slicez... not used here! v=rt.slicez(v[...,np.newaxis],land_mask, self.grid.h[i,j]*np.ones((nt,1),dtype=v.dtype), # bottom depth zeta[:,np.newaxis],self.s_params,depth, surface_masked=opts.get('surf_mask',True), spline=opts.get('spline',True))[...,0] else: # one time only v=np.interp(depth,z,v,left=np.nan,right=np.nan) v=np.ma.masked_where(np.isnan(v),v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='time series' try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords ######### if 't' in coords and self.hast(varname): if 't' in coords and 't' in self.vaxes(varname): if v.ndim==2: out.t=np.tile(self.time[times],(v.shape[0],1)) from matplotlib.dates import date2num out.tnum=np.tile(date2num(self.time[times]),(v.shape[0],1)) else: out.t=self.time[times] out.info['t']['name']='Time' out.info['tnum']=dict(name='Time',units=self.var_as['time']['units']) ### if 'z' in coords and self.hasz(varname): if 'z' in coords and 'z' in self.vaxes(varname): if not depth is None: if not isDepth: out.z=z[depth,...] else: out.z=depth+0*v else: out.z=z out.info['z']=dict(name='Depth',units='m') if 'x' in coords: out.x=lon[i,j] if self.grid.spherical: out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='X-position',units='km') if 'y' in coords: out.y=lat[i,j] if self.grid.spherical: out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Y-position',units='km') out.coordsReq=','.join(sorted(coords)) return out
def slicez(self,varname,ind,time=0,**opts): surf_mask=opts.get('surf_mask',True) spline=opts.get('spline',True) coords=opts.get('coords',self._default_coords('slicez')).split(',') out=vis.Data() out.label='slicez' out.msg=self.check_slice(varname,t=time) if out.msg: return out if not 'z' in self.vaxes(varname): return self.slicek(varname,ind,time,**opts) v=self.use(varname,SEARCHtime=time) ### x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0]) x,y,h,m=self.grid.vars(ruvp=self.vloc(varname)[0]) zeta=self.use('zeta',SEARCHtime=time) zeta=rt.rho2uvp(zeta,varname) out.v=rt.slicez(v,m,h,zeta,self.s_params,ind,surf_mask,spline) out.info['v']['name']=varname if calc.isarray(ind): out.info['v']['slice']='z= array %.2f to %.2f'%(ind.min(),ind.max()) else: out.info['v']['slice']='z=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'x' in coords: if self.grid.spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: out.z=ind+np.zeros(out.v.shape) out.info['z']=dict(name='Depth',units='m') if 't' in coords and 't' in self.vaxes(varname): out.t=self.time[time] if out.v.ndim==2: out.extra=[vis.Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.cmap']='k' out.extra[0].label='bathy' out.coordsReq=','.join(sorted(coords)) # about projection: out.set_projection(self.grid.proj_info['basemap_opts']) return out
def plot(self,coords='auto',proj='auto',labels=True,extras=True,isExtra=0,**kargs): ax=kargs.pop('ax',None) if ax: self.ax=ax parent=kargs.pop('inherit',0) if parent: self.inherit(parent) isExtra=1 if isExtra: labels=False debug_lev=kargs.pop('debug_level',0) self.set_param(**kargs) # make vfield vars 2d to simplify the process: if isinstance(self.v,tuple) and self.v[0].ndim==1: self.x=self.x[:,np.newaxis] self.y=self.y[:,np.newaxis] self.v=self.v[0][:,np.newaxis],self.v[1][:,np.newaxis] try: if isinstance(self.v,tuple): ndim=self.v[0].ndim vshape=self.v[0].shape else: ndim=self.v.ndim vshape=self.v.shape except: ndim=0 vshape=() x,y,xname,yname=None,None,None,None if coords=='auto': if ndim==2: if not self.x is None and (self.x.ndim==2 or self.x.size==vshape[1]): x,xname=self.x,'x' elif not self.d is None and (self.d.ndim==2 or self.d.size==vshape[1]): x,xname=self.d,'d' elif not self.t is None and (self.t.ndim==2 or self.t.size==vshape[1]): x,xname=self.t,'t' elif not self.tnum is None and (self.tnum.ndim==2 or self.tnum.size==vshape[1]): x,xname=self.tnum,'tnum' elif not self.y is None and (self.y.ndim==2 or self.y.size==vshape[1]): x,xname=self.y,'y' if not self.y is None and (self.y.ndim==2 or self.y.size==vshape[0]): y,yname=self.y,'y' elif not self.z is None and (self.z.ndim==2 or self.z.size==vshape[0]): y,yname=self.z,'z' elif ndim==1: y,yname=self.v,'v' if not self.d is None and self.d.ndim==1: x,xname=self.d,'d' elif not self.t is None and (calc.isarray(self.t) and self.t.ndim==1): x,xname=self.t,'t' elif not self.x is None and self.x.ndim==1: x,xname=self.x,'x' elif not self.y is None and self.y.ndim==1: x,xname=self.y,'y' elif not self.z is None and self.z.ndim==1: y,yname=self.z,'z' x,xname=self.v,'v' if ndim==2 and proj=='auto' and xname=='x' and yname=='y' and\ np.all(x>=-360) and np.all(x<=360) and np.all(y>=-90) and np.all(y<=90): proj=True elif proj=='auto': proj=False if hasattr(self,'fig') and pl.fignum_exists(self.fig.number): if isExtra: pass else: if debug_lev==2: print ' -> will clear axes' self.clear_axes() else: if hasattr(self,'ax') and pl.fignum_exists(self.ax.figure.number): if debug_lev==2: print ' -> will use previous ax' self.init_figure(ax=self.ax) else: if debug_lev==2: print ' -> will create new fig' self.init_figure() if proj and not isExtra: if not hasattr(self,'map') or self.map_info_get()!=self.map_info_current: # make a new projection: if not self.config['axes.axis'] and not x is None: self.config['axes.axis']=x.min(),x.max(),y.min(),y.max() if debug_lev==2: print ' -> new projection needed' self.init_projection(debug_level=debug_lev) ### useProj=1 # set labels: xlab=ylab=vlab='' if not xname is None: xunits=self.info[xname]['units'] if xunits in (None,'Unk'): xlab = '%s'%self.info[xname]['name'] else: xlab = '%s (%s)'%(self.info[xname]['name'],xunits) if not yname is None: yunits=self.info[yname]['units'] if yunits in (None,'Unk'): ylab = '%s'%self.info[yname]['name'] else: ylab = '%s (%s)'%(self.info[yname]['name'],yunits) vunits=self.info['v']['units'] if vunits in (None,'Unk'): vlab = '%s'%self.info['v']['name'] else: vlab = '%s (%s)'%(self.info['v']['name'],vunits) # vifield, 1d or 2d if isinstance(self.v,tuple): if debug_lev==2: print ' -> will draw vfield' self.draw_vector_field(x,y,self.v[0],self.v[1]) # sclar: else: if ndim==2: if debug_lev==2: print ' -> will draw 2d' self.draw_scalar_field(x,y,self.v) if not isExtra: self.draw_colorbar() elif ndim==1: if debug_lev==2: print ' -> will draw 1d' self.draw_1d(x,y) # add labels: if labels: if ndim==2: tit=vlab if not self.t is None: if isinstance(self.t,datetime.datetime): tit+=' $\\bullet$ %s'%self.t.strftime('%Y-%m-%d %H:%M') else: tit+=' $\\bullet$ %s to %s'%(self.t[0,0].strftime('%Y-%m-%d %H:%M'),self.t[0,-1].strftime('%Y-%m-%d %H:%M')) if not self.info['v']['slice'] in (None,'Unk'): tit+=' $\\bullet$ %s'%self.info['v']['slice'] if not tit=='Unk': self.draw_label('title',tit) if not proj:###not useProj: if not xlab=='Unk': self.draw_label('xlabel',xlab) if not ylab=='Unk': self.draw_label('ylabel',ylab) elif ndim==1: if not xlab=='Unk': self.draw_label('xlabel',xlab) if yname=='v': if not vlab=='Unk': self.draw_label('title',vlab) else: if not ylab=='Unk': self.draw_label('ylabel',ylab) if proj and not isExtra: if debug_lev==2: print ' -> will draw projection', self.info['v'] self.draw_projection() if self.extra and extras: for e in self.extra: e.inherit(self) if debug_lev==2: print ' -> will plot extras' e.plot(isExtra=1,debug_level=debug_lev)
def slicez(self,varname,ind,time=0,**opts): if not self.hasz(varname): return self.slicek(varname,ind,time,**opts) surf_nans=opts.get('surf_nans',True) spline=opts.get('spline',True) coords=opts.get('coords',self._default_coords('slicez')).split(',') out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out##None,au v=self.use(varname,SEARCHtime=time) x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) zeta=self.use('zeta',SEARCHtime=time) zeta=rt.rho2uvp(zeta,varname) v,mask=rt.slicez(v,m,h,zeta,self.s_params,ind,surf_nans,spline) v=np.ma.masked_where(mask,v) out.v=v out.info['v']['name']=varname if calc.isarray(ind): out.info['v']['slice']='z= array %.2f to %.2f'%(ind.min(),ind.max()) else: out.info['v']['slice']='z=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: out.z=ind+np.zeros(v.shape) out.info['z']=dict(name='Depth',units='m') if 't' in coords and self.hast(varname): out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out