def box_idx(self, lon, lat): """ return lat/lon index slices of the smallest containing box Designed to read from netCDF input: lon, lat: 1-D arrays (must be a regular grid) output: ii, jj: slice """ lon = rectify_longitude(lon, lon0=self.lon0) lon_llcorner, lat_llcorner, lon_urcorner, lat_urcorner = self.coords ii = (lat >= lat_llcorner) & (lat <= lat_urcorner) jj = (lon >= lon_llcorner) & (lon <= lon_urcorner) # find indices ii, jj = np.where(ii)[0], np.where(jj)[0] # make it a slice ii = slice(ii[0], ii[-1]+1) jj = slice(jj[0], jj[-1]+1) return ii, jj
def box_idx(self, lon, lat): """ return lat/lon index slices of the smallest containing box Designed to read from netCDF input: lon, lat: 1-D arrays (must be a regular grid) output: ii, jj: slice """ lon = rectify_longitude(lon, lon0=self.lon0) lon_llcorner, lat_llcorner, lon_urcorner, lat_urcorner = self.coords ii = (lat >= lat_llcorner) & (lat <= lat_urcorner) jj = (lon >= lon_llcorner) & (lon <= lon_urcorner) # find indices ii, jj = np.where(ii)[0], np.where(jj)[0] # make it a slice ii = slice(ii[0], ii[-1] + 1) jj = slice(jj[0], jj[-1] + 1) return ii, jj
def extract(self, lon, lat, data): """ extract data from the region """ if hasattr(self, 'lon0'): lon = rectify_longitude(lon, lon0 = self.lon0) ii, jj = self.box_idx(lon, lat) # for a rectangular box, box_idx exactly contains the region return lon[jj], lat[ii], data[ii, jj]
def mean(self, lon, lat, data): """ return average data over the region (weighted mean) input: lon, lat, data returns: regional mean of data """ if np.ndim(lon) == 2: raise Exception('must be a regular grid !') if hasattr(self, 'lon0'): lon = rectify_longitude(lon, lon0=self.lon0) lonr, latr, datar = self.extract(lon, lat, data) # extract regional data LO, LA = np.meshgrid(lonr, latr) w = np.cos(np.radians(LA)) # weights if isinstance(datar, np.ma.MaskedArray): datar = datar.filled(np.nan) w[np.isnan(datar)] = np.nan return np.nansum(datar * w) / np.nansum(w) # weighted mean
def extract(self, lon, lat, data): """ extract data from the region """ if hasattr(self, 'lon0'): lon = rectify_longitude(lon, lon0=self.lon0) ii, jj = self.box_idx( lon, lat) # for a rectangular box, box_idx exactly contains the region return lon[jj], lat[ii], data[ii, jj]
def plot(self, *args, **kwargs): """ plot a region same arguments as plot, except... lon0: if provided, adjust the data to have the right alignment... """ import matplotlib.pyplot as plt lons, lats = self.contour() if 'lon0' in kwargs: lons = rectify_longitude(lons, lon0 = kwargs.pop('lon0')) return plt.plot(lons, lats, *args, **kwargs)
def plot(self, *args, **kwargs): """ plot a region same arguments as plot, except... lon0: if provided, adjust the data to have the right alignment... """ import matplotlib.pyplot as plt lons, lats = self.contour() if 'lon0' in kwargs: lons = rectify_longitude(lons, lon0=kwargs.pop('lon0')) return plt.plot(lons, lats, *args, **kwargs)
def contains(self, lon, lat): """ return True if x, y is in the Polygon """ if np.size(lon) > 1: #return np.array([self.contains(xx, yy) for xx, yy in zip(lon, lat)]) return self.contains_arrays(lon, lat) from shapely.geometry import Point poly = self.to_shapely() lon = rectify_longitude(lon, lon0=self.lon0, sort=False) res = poly.contains(Point(lon, lat)) assert res is not None return res
def contains_arrays(self, lon, lat): """ return an array of same size as lon and lat lon, lat: arrays of longitude and latitude """ from matplotlib.nxutils import points_inside_poly as inpoly lon = np.asarray(lon) lat = np.asarray(lat) lon = rectify_longitude(lon, lon0=self.lon0, sort=False) #if lon.ndim == 1: # lon, lat = np.meshgrid(lon, lat) xypoints = np.vstack((lon.flatten(), lat.flatten())).T xyvertices = np.asarray(self.to_shapely().exterior.xy).T # contours of the polynom mask = inpoly(xypoints, xyvertices) return mask.reshape(lon.shape)
def contains_arrays(self, lon, lat): """ return an array of same size as lon and lat lon, lat: arrays of longitude and latitude """ from matplotlib.nxutils import points_inside_poly as inpoly lon = np.asarray(lon) lat = np.asarray(lat) lon = rectify_longitude(lon, lon0=self.lon0, sort=False) #if lon.ndim == 1: # lon, lat = np.meshgrid(lon, lat) xypoints = np.vstack((lon.flatten(), lat.flatten())).T xyvertices = np.asarray( self.to_shapely().exterior.xy).T # contours of the polynom mask = inpoly(xypoints, xyvertices) return mask.reshape(lon.shape)
def mean(self, lon, lat, data): """ return average data over the region (weighted mean) input: lon, lat, data returns: regional mean of data """ if np.ndim(lon) == 2: raise Exception('must be a regular grid !') if hasattr(self, 'lon0'): lon = rectify_longitude(lon, lon0 = self.lon0) lonr, latr, datar = self.extract(lon, lat, data) # extract regional data LO, LA = np.meshgrid(lonr, latr) w = np.cos(np.radians(LA)) # weights if isinstance(datar, np.ma.MaskedArray): datar = datar.filled(np.nan) w[np.isnan(datar)] = np.nan return np.nansum(datar*w)/np.nansum(w) # weighted mean