def mask_direction_data(): print('Masking flow direction data') if not os.path.isfile(direction_location): import rasterio.mask from shapely.geometry import box west, south, east, north = globals.bounds(1) polygon = box(west, south, east, north) data = rasterio.open('data_hydrosheds/as_dir_15s_bil/as_dir_15s.bil') out_image, out_transform = rasterio.mask.mask(data, [polygon], crop=True) out_meta = data.meta.copy() out_meta.update({ "height": out_image.shape[1], "width": out_image.shape[2], "transform": out_transform }) with rasterio.open(direction_location, "w", **out_meta) as dest: dest.write(out_image) out_meta.update({ "driver": "GTiff", "height": out_image.shape[1], "width": out_image.shape[2], "transform": out_transform }) with rasterio.open( 'data_hydrosheds/as_dir_15s_bil/as_dir_15s-masked.tif', "w", **out_meta) as dest: dest.write(out_image)
def plot_river_map_2(dataframe, split=200, figsize=(4, 3), printoption=False, filename=False): fig, ax = plot_map(facecolor=True, figsize=figsize, printoption=printoption) logsplit = np.log10(split) if printoption: range_max = 0.6 range_min = 0.05 else: range_max = 0.4 range_min = 0.025 logflow = dataframe['Log_Q_avg'] flow = 10**logflow logflow = np.log10(flow + 1) width = ( (logflow - logflow.min()) * (range_max - range_min)) / (logflow.max() - logflow.min()) + range_min dataframe['linewidth'] = width crs_proj4 = ax.projection.proj4_init dataframe = dataframe.to_crs(crs_proj4) data1 = dataframe[dataframe['Log_Q_avg'] <= logsplit] width1 = data1['linewidth'] data1.plot(ax=ax, color='b', linewidth=width1) data2 = dataframe[dataframe['Log_Q_avg'] > logsplit] width2 = data2['linewidth'] data2.plot(ax=ax, color='r', linewidth=width2) from matplotlib.lines import Line2D custom_lines = [ Line2D([0], [0], color='b', lw=0.3), Line2D([0], [0], color='r', lw=0.5), ] ax.legend(custom_lines, ['River reach', 'Avg flow > ' + str(split) + ' m$^3$/s']) bounds = globals.bounds(0.2) west, south, east, north = bounds north += 1 south -= 1.2 ax.set_extent([west, east, south, north]) ax.set_yticks(range(int(np.ceil(south)), int(np.floor(north)) + 1, 2), crs=ccrs.PlateCarree()) if filename: plt.title("Watershed created from Gloric dataset") plt.savefig(filename, bbox_inches='tight') return (fig, ax)
def plot_map(facecolor=False, figsize=(4, 3), printoption=False): fig, ax = base_map(figsize, printoption=printoption) if not facecolor: face_land = face_ocean = 'none' elif facecolor: face_land = '#efefdb' face_ocean = '#a3dafc' land = cfeature.NaturalEarthFeature('cultural', 'admin_0_countries', '50m', edgecolor='k', linewidth=0.3, facecolor=face_land) #efefdb, #e9ebe0 ocean = cfeature.NaturalEarthFeature('physical', 'ocean', '50m', edgecolor='k', linewidth=0.3, facecolor=face_ocean) bounds = globals.bounds(0.2) west, south, east, north = bounds south -= 1.2 x = np.floor(east) y = np.ceil(south) - 0.3 ax.add_feature(land) ax.add_feature(ocean) plt.arrow(x, y, 0, 1, length_includes_head=True, width=0.05, head_width=0.2, facecolor='k') return (fig, ax)
import traceback import logging import pandas as pd import matplotlib.pyplot as plt import numpy as np import os import re import csv import h5py from geopy import distance import helper_functions import globals bounds = globals.bounds(2) padma = pd.read_pickle('data_gloric/padma_gloric_1m3_final_no_geo.pkl') padma = padma.set_index('Reach_ID',drop=True) padma = padma[['Next_down', 'Length_km']] class RainGrid: def __init__(self, filename, date): gpm_data = helper_functions.GPM('data_pmm/raw/{}/'.format(date)+filename, bounds) self.rain_grid = gpm_data.get_crop() self.grid_bounds = gpm_data.get_bounds() self.file_name = re.search('3B-HHR.MS.MRG.3IMERG.(.*?).V06B.HDF5', filename).group(1) self.date = date def plot_rain_distribution(self):
def get_reach_coords(): """Get reach coordinates in both latlon and rain grid indexes Parameters: - None Returns: - reaches: pandas.DataFrame with columns=['Reach_ID', 'Lat_Lon', 'Avg_pixel', 'Grid_coords']. 'Lat_Lon' is a (lat,lon) tuple with the latitude and longitude of the geometric center of the reach; 'Avg_pixel' is a (h, w) tuple where h and w are the coordinatesof the geometric center of the reach in TIF image pixels; 'Grid_coords' is a (i,j) tuple where i and j are the rain grid coordinates of the geometric center of the reach """ # We have pixels of every reach. Now we are going to get the center of mass pixel # for every reach, and translate this to latitude and longitude import pandas as pd import globals bounds = globals.bounds(2) areas = pd.read_pickle('data_gloric/areas_gloric_pixel.pkl')['pixels'].to_numpy() avg_pixels = [] for row in areas: nr_pixels = len(row) avg_height = 0 avg_width = 0 for pixel in row: avg_height += pixel[0] avg_width += pixel[1] avg_pixels.append((avg_height/nr_pixels, avg_width/nr_pixels)) reaches = pd.read_pickle('data_gloric/areas_gloric_pixel.pkl')[['Reach_ID','pixels']] reaches['Avg_pixel'] = avg_pixels # pixels_height and pixels_width in pixels of tif image (use any of the masked tifs) pixels_height, pixels_width = rasterio.open('data_pmm/tif/2013-06-16/3B-HHR.MS.MRG.3IMERG' '.20130616-S000000-E002959.0000.V06B.HDF5-masked-resampled.tif').read(1).shape def pixel_to_coords(ij): """Convert pixel to latitude and longitude""" i, j = ij[0], ij[1] return (bounds[1]+i*(bounds[3]-bounds[1])/pixels_width, bounds[0]+j*(bounds[2]-bounds[0])/pixels_height) rain_grid = GPM('data_pmm/raw/2013-06-16/3B-HHR.MS.MRG.3IMERG.' '20130616-S000000-E002959.0000.V06B.HDF5', bounds).get_crop() def pixels_to_rain_grid_index(ij): """Converts avalanche pixels form TIF image into rain_grid index. Parameters: - avalanche_pixels: (h, w) tuple where h is the height coordinate and w the width coordinate for the avalanche geometric center in pixels of the TIF image.""" i, j = ij # (rg_height,rg_width) is the shape of the rain_grid rg_height, rg_width = len(rain_grid), len(rain_grid[0]) avalanche_i = round(i*(rg_height/pixels_height)) avalanche_j = round(j*(rg_width/pixels_width)) return avalanche_i, avalanche_j reaches['Lat_Lon'] = [pixel_to_coords(ij=ij) for ij in reaches.loc[:, 'Avg_pixel']] reaches['Grid_coords'] = [pixels_to_rain_grid_index(ij=ij) for ij in reaches.loc[:, 'Avg_pixel']] reaches = reaches.drop(columns=[ 'Reach_ID', 'pixels'] ) return reaches
def base_map(figsize=(4, 3), printoption=False): if printoption: fig = plt.figure(dpi=600, figsize=figsize) else: fig = plt.figure(dpi=300, figsize=figsize) #fig = plt.figure(dpi=300,figsize=(9.3,6.2)) crs = ccrs.PlateCarree() ax = plt.axes(projection=crs) bounds = globals.bounds(0.2) west, south, east, north = bounds south -= 1.2 ax.set_extent([west, east, south, north]) ax.set_xticks(range(int(np.ceil(west) + 1), int(np.floor(east) + 1), 2), crs=ccrs.PlateCarree()) ax.set_yticks(range(int(np.ceil(south)), int(np.floor(north)), 2), crs=ccrs.PlateCarree()) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) ax.xaxis.tick_top() ax.tick_params(which='both', direction="in", width=0.5, length=2) if printoption == False: matplotlib.rcParams.update({ "font.size": 6.0, #'lines.linewidth':0.6, 'patch.linewidth': 0.5, "axes.titlesize": 6, "axes.labelsize": 4, 'xtick.labelsize': 4, 'ytick.labelsize': 4, 'legend.fontsize': 4, 'pgf.rcfonts': False }) elif printoption == True: print('Selected print option') matplotlib.rcParams.update({ "font.size": 6.0, #'lines.linewidth':0.6, 'patch.linewidth': 0.5, "axes.titlesize": 6, "axes.labelsize": 6, 'xtick.labelsize': 6, 'ytick.labelsize': 6, 'legend.fontsize': 6, 'pgf.rcfonts': False }) x = np.floor(east) y = np.ceil(south) - 0.3 plt.arrow(x, y, 0, 1, length_includes_head=True, width=0.05, head_width=0.2, facecolor='k') plt.text(x + 0.4, y + 0.4, 'N', size=5, va='center', ha='center') fontprops = fm.FontProperties(size=4) asb = AnchoredSizeBar(ax.transData, 2, '200 km', loc=3, label_top=True, pad=0.1, borderpad=0.6, sep=1, frameon=False, fontproperties=fontprops, size_vertical=0.07) ax.add_artist(asb) return (fig, ax)