def plot_raster(self, res=None, raster_res=None, save_tiff=None, raster_f=lambda x: np.log10((np.fmax(x+1, 1))), label='value (log10)', scheduler=None, axis=None, **kwargs): """ Generate raster from points geometry and plot it using log10 scale: np.log10((np.fmax(raster+1, 1))). Parameters: res (float, optional): resolution of current data in units of latitude and longitude, approximated if not provided. raster_res (float, optional): desired resolution of the raster save_tiff (str, optional): file name to save the raster in tiff format, if provided raster_f (lambda function): transformation to use to data. Default: log10 adding 1. label (str): colorbar label scheduler (str): used for dask map_partitions. “threads”, “synchronous” or “processes” axis (matplotlib.axes._subplots.AxesSubplot, optional): axis to use kwargs (optional): arguments for imshow matplotlib function Returns: matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot """ if self.meta and self.meta['height']*self.meta['width'] == len(self): raster = self.value.values.reshape((self.meta['height'], self.meta['width'])) # check raster starts by upper left corner if self.latitude.values[0] < self.latitude.values[-1]: raster = np.flip(raster, axis=0) if self.longitude.values[0] > self.longitude.values[-1]: LOGGER.error('Points are not ordered according to meta raster.') raise ValueError else: raster, meta = co.points_to_raster(self, ['value'], res, raster_res, scheduler) raster = raster.reshape((meta['height'], meta['width'])) # save tiff if save_tiff is not None: ras_tiff = rasterio.open(save_tiff, 'w', driver='GTiff', \ height=meta['height'], width=meta['width'], count=1, \ dtype=np.float32, crs=self.crs, transform=meta['transform']) ras_tiff.write(raster.astype(np.float32), 1) ras_tiff.close() # make plot crs_epsg, _ = u_plot.get_transformation(self.crs) xmin, ymin, xmax, ymax = self.longitude.min(), self.latitude.min(), \ self.longitude.max(), self.latitude.max() if not axis: _, axis = u_plot.make_map(proj=crs_epsg) cbar_ax = make_axes_locatable(axis).append_axes('right', size="6.5%", \ pad=0.1, axes_class=plt.Axes) axis.set_extent([max(xmin, crs_epsg.x_limits[0]), \ min(xmax, crs_epsg.x_limits[1]), max(ymin, crs_epsg.y_limits[0]), \ min(ymax, crs_epsg.y_limits[1])], crs_epsg) u_plot.add_shapes(axis) imag = axis.imshow(raster_f(raster), **kwargs, origin='upper', extent=[xmin, xmax, ymin, ymax], transform=crs_epsg) plt.colorbar(imag, cax=cbar_ax, label=label) plt.draw() return axis
def plot_raster(self, res=None, raster_res=None, save_tiff=None, raster_f=lambda x: np.log10((np.fmax(x+1, 1))), label='value (log10)', **kwargs): """ Generate raster from points geometry and plot it using log10 scale: np.log10((np.fmax(raster+1, 1))). Parameters: res (float, optional): resolution of current data in units of latitude and longitude, approximated if not provided. raster_res (float, optional): desired resolution of the raster save_tiff (str, optional): file name to save the raster in tiff format, if provided raster_f (lambda function): transformation to use to data. Default: log10 adding 1. label (str): colorbar label kwargs (optional): arguments for imshow matplotlib function Returns: matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot """ if not 'geometry' in self.columns: self.set_geometry_points() crs_epsg, crs_unit = self._get_transformation() if not res: res= min(get_resolution(self.latitude.values, self.longitude.values)) if not raster_res: raster_res = res LOGGER.info('Raster from resolution %s%s to %s%s.', res, crs_unit, raster_res, crs_unit) exp_poly = self[['value']].set_geometry(self.buffer(res/2).envelope) # construct raster xmin, ymin, xmax, ymax = self.total_bounds rows, cols, ras_trans = points_to_raster((xmin, ymin, xmax, ymax), raster_res) raster = rasterize([(x, val) for (x, val) in zip(exp_poly.geometry, exp_poly.value)], out_shape=(rows, cols), transform=ras_trans, fill=0, all_touched=True, dtype=rasterio.float32, ) # save tiff if save_tiff is not None: ras_tiff = rasterio.open(save_tiff, 'w', driver='GTiff', \ height=raster.shape[0], width=raster.shape[1], count=1, \ dtype=np.float32, crs=self.crs, transform=ras_trans) ras_tiff.write(raster.astype(np.float32), 1) ras_tiff.close() # make plot fig, axis = u_plot.make_map(proj=crs_epsg) cbar_ax = fig.add_axes([0.99, 0.238, 0.03, 0.525]) fig.subplots_adjust(hspace=0, wspace=0) axis[0, 0].set_extent([max(xmin, crs_epsg.x_limits[0]), min(xmax, crs_epsg.x_limits[1]), max(ymin, crs_epsg.y_limits[0]), min(ymax, crs_epsg.y_limits[1])], crs_epsg) u_plot.add_shapes(axis[0, 0]) imag = axis[0, 0].imshow(raster_f(raster), **kwargs, origin='upper', extent=[xmin, xmax, ymin, ymax], transform=crs_epsg) plt.colorbar(imag, cax=cbar_ax, label=label) plt.draw() posn = axis[0, 0].get_position() cbar_ax.set_position([posn.x0 + posn.width + 0.01, posn.y0, 0.04, posn.height]) return fig, axis
def set_lat_lon_to_meta(self): """ Compute meta from lat and lon values. To match the existing lat and lon, lat and lon need to start from the upper left corner!!""" self.meta = dict() res = min(get_resolution(self.lat, self.lon)) rows, cols, ras_trans = points_to_raster(self.total_bounds, res) LOGGER.debug('Resolution points: %s', str(res)) self.meta = { 'width': cols, 'height': rows, 'crs': self.crs, 'transform': ras_trans }
def set_raster_from_pnt_bounds(self, points_bounds, res, crs=DEF_CRS): """ Set raster metadata (meta attribute) from points border data. Raster border = point_border + res/2 Parameters: points_bounds (tuple): points' lon_min, lat_min, lon_max, lat_max res (float): desired resolution in same units as points_bounds crs (dict() or rasterio.crs.CRS, optional): CRS. Default: DEF_CRS """ self.__init__() rows, cols, ras_trans = points_to_raster(points_bounds, res) self.set_raster_from_pix_bounds(ras_trans[5], ras_trans[2], ras_trans[4], ras_trans[0], rows, cols, crs)
def test_vector_to_raster_pass(self): """ Test vector_to_raster """ xmin, ymin, xmax, ymax = -60, -5, -50, 10 # bounds of points == centers pixels points_bounds = (xmin, ymin, xmax, ymax) res = 0.5 rows, cols, ras_trans = points_to_raster(points_bounds, res) self.assertEqual(xmin - res / 2 + res * cols, xmax + res / 2) self.assertEqual(ymax + res / 2 - res * rows, ymin - res / 2) self.assertEqual(ras_trans[0], res) self.assertEqual(ras_trans[4], -res) self.assertEqual(ras_trans[1], 0.0) self.assertEqual(ras_trans[3], 0.0) self.assertEqual(ras_trans[2], xmin - res / 2) self.assertEqual(ras_trans[5], ymax + res / 2)
def test_points_to_raster_pass(self): """Test points_to_raster""" df_val = gpd.GeoDataFrame(crs={'init': 'epsg:2202'}) x, y = np.meshgrid(np.linspace(0, 2, 5), np.linspace(40, 50, 10)) df_val['latitude'] = y.flatten() df_val['longitude'] = x.flatten() df_val['value'] = np.ones(len(df_val)) * 10 _raster, meta = points_to_raster(df_val, val_names=['value']) self.assertTrue(equal_crs(meta['crs'], df_val.crs)) self.assertAlmostEqual(meta['transform'][0], 0.5) self.assertAlmostEqual(meta['transform'][1], 0) self.assertAlmostEqual(meta['transform'][2], -0.25) self.assertAlmostEqual(meta['transform'][3], 0) self.assertAlmostEqual(meta['transform'][4], -0.5) self.assertAlmostEqual(meta['transform'][5], 50.25) self.assertEqual(meta['height'], 21) self.assertEqual(meta['width'], 5) # test for values crossing antimeridian df_val = gpd.GeoDataFrame(crs=DEF_CRS) df_val['latitude'] = [1, 0, 1, 0] df_val['longitude'] = [178, -179.0, 181, -180] df_val['value'] = np.arange(4) r_data, meta = points_to_raster(df_val, val_names=['value'], res=0.5, raster_res=1.0) self.assertTrue(equal_crs(meta['crs'], df_val.crs)) self.assertAlmostEqual(meta['transform'][0], 1.0) self.assertAlmostEqual(meta['transform'][1], 0) self.assertAlmostEqual(meta['transform'][2], 177.5) self.assertAlmostEqual(meta['transform'][3], 0) self.assertAlmostEqual(meta['transform'][4], -1.0) self.assertAlmostEqual(meta['transform'][5], 1.5) self.assertEqual(meta['height'], 2) self.assertEqual(meta['width'], 4) np.testing.assert_array_equal(r_data[0], [[0, 0, 0, 2], [0, 0, 3, 1]])
def test_points_to_raster_pass(self): """ Test points_to_raster """ df_val = gpd.GeoDataFrame(crs={'init': 'epsg:2202'}) x, y = np.meshgrid(np.linspace(0, 2, 5), np.linspace(40, 50, 10)) df_val['latitude'] = y.flatten() df_val['longitude'] = x.flatten() df_val['value'] = np.ones(len(df_val)) * 10 raster, meta = points_to_raster(df_val, val_names=['value']) self.assertTrue(equal_crs(meta['crs'], df_val.crs)) self.assertAlmostEqual(meta['transform'][0], 0.5) self.assertAlmostEqual(meta['transform'][1], 0) self.assertAlmostEqual(meta['transform'][2], -0.25) self.assertAlmostEqual(meta['transform'][3], 0) self.assertAlmostEqual(meta['transform'][4], -0.5) self.assertAlmostEqual(meta['transform'][5], 50.25) self.assertEqual(meta['height'], 21) self.assertEqual(meta['width'], 5)
def write_raster(self, file_name, value_name='value', scheduler=None): """ Write value data into raster file with GeoTiff format Parameters: file_name (str): name output file in tif format """ if self.meta and self.meta['height']*self.meta['width'] == len(self): raster = self[value_name].values.reshape((self.meta['height'], self.meta['width'])) # check raster starts by upper left corner if self.latitude.values[0] < self.latitude.values[-1]: raster = np.flip(raster, axis=0) if self.longitude.values[0] > self.longitude.values[-1]: LOGGER.error('Points are not ordered according to meta raster.') raise ValueError co.write_raster(file_name, raster, self.meta) else: raster, meta = co.points_to_raster(self, [value_name], scheduler=scheduler) co.write_raster(file_name, raster, meta)
def plot_raster(self, res=None, raster_res=None, save_tiff=None, raster_f=lambda x: np.log10((np.fmax(x + 1, 1))), label='value (log10)', scheduler=None, axis=None, figsize=(9, 13), **kwargs): """Generate raster from points geometry and plot it using log10 scale: np.log10((np.fmax(raster+1, 1))). Parameters: res (float, optional): resolution of current data in units of latitude and longitude, approximated if not provided. raster_res (float, optional): desired resolution of the raster save_tiff (str, optional): file name to save the raster in tiff format, if provided raster_f (lambda function): transformation to use to data. Default: log10 adding 1. label (str): colorbar label scheduler (str): used for dask map_partitions. “threads”, “synchronous” or “processes” axis (matplotlib.axes._subplots.AxesSubplot, optional): axis to use figsize (tuple, optional): figure size for plt.subplots kwargs (optional): arguments for imshow matplotlib function Returns: matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot """ if self.meta and self.meta.get('height', 0) * self.meta.get( 'height', 0) == len(self.gdf): raster = self.gdf.value.values.reshape( (self.meta['height'], self.meta['width'])) # check raster starts by upper left corner if self.gdf.latitude.values[0] < self.gdf.latitude.values[-1]: raster = np.flip(raster, axis=0) if self.gdf.longitude.values[0] > self.gdf.longitude.values[-1]: LOGGER.error( 'Points are not ordered according to meta raster.') raise ValueError else: raster, meta = u_coord.points_to_raster(self.gdf, ['value'], res, raster_res, scheduler) raster = raster.reshape((meta['height'], meta['width'])) # save tiff if save_tiff is not None: with rasterio.open(save_tiff, 'w', driver='GTiff', height=meta['height'], width=meta['width'], count=1, dtype=np.float32, crs=self.crs, transform=meta['transform']) as ras_tiff: ras_tiff.write(raster.astype(np.float32), 1) # make plot proj_data, _ = u_plot.get_transformation(self.crs) proj_plot = proj_data if isinstance(proj_data, ccrs.PlateCarree): # use different projections for plot and data to shift the central lon in the plot xmin, ymin, xmax, ymax = u_coord.latlon_bounds( self.gdf.latitude.values, self.gdf.longitude.values) proj_plot = ccrs.PlateCarree(central_longitude=0.5 * (xmin + xmax)) else: xmin, ymin, xmax, ymax = (self.gdf.longitude.min(), self.gdf.latitude.min(), self.gdf.longitude.max(), self.gdf.latitude.max()) if not axis: _, axis = u_plot.make_map(proj=proj_plot, figsize=figsize) cbar_ax = make_axes_locatable(axis).append_axes('right', size="6.5%", pad=0.1, axes_class=plt.Axes) axis.set_extent((xmin, xmax, ymin, ymax), crs=proj_data) u_plot.add_shapes(axis) imag = axis.imshow(raster_f(raster), **kwargs, origin='upper', extent=(xmin, xmax, ymin, ymax), transform=proj_data) plt.colorbar(imag, cax=cbar_ax, label=label) plt.draw() return axis
def plot_raster(self, res=None, raster_res=None, save_tiff=None, raster_f=lambda x: np.log10((np.fmax(x + 1, 1))), label='value (log10)', scheduler=None, axis=None, figsize=(9, 13), fill=True, adapt_fontsize=True, **kwargs): """Generate raster from points geometry and plot it using log10 scale: np.log10((np.fmax(raster+1, 1))). Parameters ---------- res : float, optional resolution of current data in units of latitude and longitude, approximated if not provided. raster_res : float, optional desired resolution of the raster save_tiff : str, optional file name to save the raster in tiff format, if provided raster_f : lambda function transformation to use to data. Default: log10 adding 1. label : str colorbar label scheduler : str used for dask map_partitions. “threads”, “synchronous” or “processes” axis : matplotlib.axes._subplots.AxesSubplot, optional axis to use figsize : tuple, optional figure size for plt.subplots fill : bool, optional If false, the areas with no data will be plotted in white. If True, the areas with missing values are filled as 0s. The default is True. adapt_fontsize : bool, optional If set to true, the size of the fonts will be adapted to the size of the figure. Otherwise the default matplotlib font size is used. Default is True. kwargs : optional arguments for imshow matplotlib function Returns ------- matplotlib.figure.Figure, cartopy.mpl.geoaxes.GeoAxesSubplot """ if self.meta and self.meta.get('height', 0) * self.meta.get( 'height', 0) == len(self.gdf): raster = self.gdf.value.values.reshape( (self.meta['height'], self.meta['width'])) # check raster starts by upper left corner if self.gdf.latitude.values[0] < self.gdf.latitude.values[-1]: raster = np.flip(raster, axis=0) if self.gdf.longitude.values[0] > self.gdf.longitude.values[-1]: raise ValueError( 'Points are not ordered according to meta raster.') else: raster, meta = u_coord.points_to_raster(self.gdf, ['value'], res, raster_res, scheduler) raster = raster.reshape((meta['height'], meta['width'])) # save tiff if save_tiff is not None: with rasterio.open(save_tiff, 'w', driver='GTiff', height=meta['height'], width=meta['width'], count=1, dtype=np.float32, crs=self.crs, transform=meta['transform']) as ras_tiff: ras_tiff.write(raster.astype(np.float32), 1) # make plot proj_data, _ = u_plot.get_transformation(self.crs) proj_plot = proj_data if isinstance(proj_data, ccrs.PlateCarree): # use different projections for plot and data to shift the central lon in the plot xmin, ymin, xmax, ymax = u_coord.latlon_bounds( self.gdf.latitude.values, self.gdf.longitude.values) proj_plot = ccrs.PlateCarree(central_longitude=0.5 * (xmin + xmax)) else: xmin, ymin, xmax, ymax = (self.gdf.longitude.min(), self.gdf.latitude.min(), self.gdf.longitude.max(), self.gdf.latitude.max()) if not axis: _, axis, fontsize = u_plot.make_map(proj=proj_plot, figsize=figsize, adapt_fontsize=adapt_fontsize) else: fontsize = None cbar_ax = make_axes_locatable(axis).append_axes('right', size="6.5%", pad=0.1, axes_class=plt.Axes) axis.set_extent((xmin, xmax, ymin, ymax), crs=proj_data) u_plot.add_shapes(axis) if not fill: raster = np.where(raster == 0, np.nan, raster) raster_f = lambda x: np.log10((np.maximum(x + 1, 1))) if 'cmap' not in kwargs: kwargs['cmap'] = CMAP_RASTER imag = axis.imshow(raster_f(raster), **kwargs, origin='upper', extent=(xmin, xmax, ymin, ymax), transform=proj_data) cbar = plt.colorbar(imag, cax=cbar_ax, label=label) plt.colorbar(imag, cax=cbar_ax, label=label) plt.tight_layout() plt.draw() if fontsize: cbar.ax.tick_params(labelsize=fontsize) cbar.ax.yaxis.get_offset_text().set_fontsize(fontsize) for item in [axis.title, cbar.ax.xaxis.label, cbar.ax.yaxis.label]: item.set_fontsize(fontsize) return axis