def plot_cell_grid_partitioning(output, cellsize_lon=5.0, cellsize_lat=5.0, figsize=(12, 6)): """ Plot an overview of a global cell partitioning. Parameters ---------- output: string output file name """ mp.rcParams["font.size"] = 10 mp.rcParams["text.usetex"] = True plt.figure(figsize=figsize, dpi=300) ax = plt.axes([0, 0, 1, 1]) map = Basemap( projection="cyl", llcrnrlat=-90, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180, ax=ax, ) map.drawparallels(np.arange(-90, 90, cellsize_lat), labels=[1, 0, 0, 0], linewidth=0.5) map.drawmeridians( np.arange(-180, 180, cellsize_lon), labels=[0, 0, 0, 1], rotation="vertical", linewidth=0.5, ) # fill continents 'coral' (with zorder=0), color wet areas 'aqua' map.drawmapboundary(fill_color="aqua") map.fillcontinents(color="0.6", lake_color="aqua") label_lats = np.arange(-90 + cellsize_lat / 2.0, 90, cellsize_lat) label_lons = np.arange(-180 + cellsize_lon / 2.0, 180, cellsize_lon) lons, lats = np.meshgrid(label_lons, label_lats) x, y = map(lons.flatten(), lats.flatten()) cells = grids.lonlat2cell( lons.flatten(), lats.flatten(), cellsize_lon=cellsize_lon, cellsize_lat=cellsize_lat, ) for xt, yt, cell in zip(x, y, cells): plt.text( xt, yt, "{:}".format(cell), fontsize=4, va="center", ha="center", weight="bold", ) plt.savefig(output, format="png", dpi=300) plt.close()
def testlonlat2cell_edge(self): """ Use points on the 180 degree longitude and see if they fall into the correct cell """ lats = [69.8242, 69.122, 68.42] lons = [180, 180, 180] cells = lonlat2cell(lons, lats) assert list(cells) == [31, 31, 31]
def testlonlat2cell_hist(self): """ Setup grid with unequal cell size along lat and lon and test if the correct number of points lay in each cell. """ cells = lonlat2cell( self.lons, self.lats, cellsize_lon=15, cellsize_lat=30) hist, bin_edges = np.histogram( cells.flatten(), bins=len(np.unique(cells))) nptest.assert_allclose(hist, np.zeros_like(hist) + 72)
def testlonlat2cell_hist(self): """ Setup grid with unequal cell size along lat and lon and test if the correct number of points lay in each cell. """ cells = lonlat2cell(self.lons, self.lats, cellsize_lon=15, cellsize_lat=30) hist, bin_edges = np.histogram(cells.flatten(), bins=len(np.unique(cells))) nptest.assert_allclose(hist, np.zeros_like(hist) + 72)
def __init__(self, bbox=None): """ Parameters ---------- bbox: tuple, optional (default: None) (min_lon, min_lat, max_lon, max_lat) Bounding box to create subset for, if None is passed a global grid is used. """ ease25 = EASE2_grid(25000) lons, lats = ease25.londim, ease25.latdim lons, lats = np.meshgrid(lons, lats) assert lons.shape == lats.shape shape = lons.shape lats = np.flipud(lats) # flip lats, so that origin in bottom left lons, lats = lons.flatten(), lats.flatten() globgrid = BasicGrid(lons, lats, shape=shape) sgpis = globgrid.activegpis self.bbox = bbox if self.bbox: sgpis = globgrid.get_bbox_grid_points(latmin=self.bbox[1], latmax=self.bbox[3], lonmin=self.bbox[0], lonmax=self.bbox[2]) self.cellsize = 5. super(EASE25CellGrid, self).__init__(lon=globgrid.arrlon, lat=globgrid.arrlat, subset=sgpis, cells=lonlat2cell(globgrid.arrlon, globgrid.arrlat, self.cellsize), shape=shape) self.subset_shape = (len(np.unique(self.activearrlat)), len(np.unique(self.activearrlon)))
def __init__(self, lon, lat, cellsize=5., gpis=None, geodatum='WGS84', subset=None, setup_kdTree=False, **kwargs): self.cellsize = cellsize cells = lonlat2cell(lon, lat, cellsize=cellsize) super(RegularCellGrid, self).__init__(lon, lat, cells, gpis, geodatum, subset=subset, setup_kdTree=setup_kdTree, **kwargs) self.dx, self.dy = self._grid_space()
def plot_cell_grid_partitioning(output, cellsize_lon=5., cellsize_lat=5.0, figsize=(12, 6)): """ Plot an overview of a global cell partitioning. Parameters ---------- output: string output file name """ mp.rcParams['font.size'] = 10 mp.rcParams['text.usetex'] = True plt.figure(figsize=figsize, dpi=300) ax = plt.axes([0, 0, 1, 1]) map = Basemap(projection="cyl", llcrnrlat=-90, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180, ax=ax) map.drawparallels(np.arange(-90, 90, cellsize_lat), labels=[1, 0, 0, 0], linewidth=0.5) map.drawmeridians(np.arange(-180, 180, cellsize_lon), labels=[0, 0, 0, 1], rotation='vertical', linewidth=0.5) # fill continents 'coral' (with zorder=0), color wet areas 'aqua' map.drawmapboundary(fill_color='aqua') map.fillcontinents(color='0.6', lake_color='aqua') label_lats = np.arange(-90 + cellsize_lat / 2., 90, cellsize_lat) label_lons = np.arange(-180 + cellsize_lon / 2., 180, cellsize_lon) lons, lats = np.meshgrid(label_lons, label_lats) x, y = map(lons.flatten(), lats.flatten()) cells = grids.lonlat2cell(lons.flatten(), lats.flatten(), cellsize_lon=cellsize_lon, cellsize_lat=cellsize_lat) for xt, yt, cell in zip(x, y, cells): plt.text(xt, yt, "{:}".format(cell), fontsize=4, va="center", ha="center", weight="bold") plt.savefig(output, format='png', dpi=300) plt.close()
def meshgrid(resolution=0.25, cellsize=5., flip_lats=False, lon_range=None, lat_range=None): """ Create arrays that are used as input to create a smecv_grid. Parameters ---------- resolution : float, optional (default: 0.25) Grid resolution in lon/lat dimension, degrees cellsize : float, optional (default: 0.25) Cell resolution in lon/lat dimension, degrees flip_lats : bool, optional (default: False) Flip the lats, gpis and cells stored in the grid. This means that each lonlat will still have the correct gpi/cell number, but self.arrgpi[gpi] will NOT return the correct gpi, i.e the gpi can't be used to index the arrays. This option was used in grid v4 and changed afterwards and is kept for backwards compatibility. Should NOT be used anymore. ------------------------------------------------------------------------ e.g. SMECV_Grid_v042(None).activegpis[0] is 1035360 and SMECV_Grid_v042(None).activearrlat[0] is 89.875 but SMECV_Grid_v052(None).activegpis[0] is 0, and SMECV_Grid_v052(None).activearrlat[0] is -89.875 e.g. grid.find_nearest_gpi(-100.375,38.375) will return in both versions (739038, 0.0) but SMECV_Grid_v042(None).arrlat[739038] is -38.375 and not 38.375 as it is in v5. lon_range : tuple, optional (default: None) min_lon, max_lon : Limit meshgrid to lons in range, if None is set, a global grid is created. lat_range : tuple, optional (default: None) min_lat, max_lat : Limit meshgrid to lats in range, if None is net, a global grid is created. Returns ------- lon : np.array Global flattened longitudes for ALL gpis lat : np.array Global flattened latitudes for ALL gpis gpis : np.array Global gpis, with gpi 0 close to (-180,-90) cells : np.array Global cells, with cell 0 starting close to (-180,-90) shape : tuple rows and columns, i.e. unique lats, lons in the global grid """ glob_lons = safe_arange(-180 + resolution / 2, 180 + resolution / 2, resolution) glob_lats = safe_arange(-90 + resolution / 2, 90 + resolution / 2, resolution) lon, lat = np.meshgrid(glob_lons, glob_lats) shape = (len(glob_lats), len(glob_lons)) gpis = np.arange(shape[0] * shape[1]).reshape(shape) if flip_lats: lat = np.flipud(lat) gpis = np.flipud(gpis) if lon_range is not None: lon_slice = range2slice(glob_lons, lon_range) else: lon_slice = slice(None, None) if lat_range is not None: lat_slice = range2slice(glob_lats, lat_range) else: lat_slice = slice(None, None) lat = lat[lat_slice, lon_slice] lon = lon[lat_slice, lon_slice] shape = lon.shape gpis = gpis[lat_slice, lon_slice] assert gpis.shape == lat.shape == shape lat = lat.flatten() lon = lon.flatten() gpis = gpis.flatten() cells = lonlat2cell(lon, lat, cellsize, None, None) return lon, lat, gpis, cells, shape