def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, obs_path=None): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf( file_path=rconfig.data_path) obs_query_params = dict(start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) # Calculate daily mean temperatures as T = (T(min) + T(max)) * 0.5 if vname == "TT": tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) # SWE elif vname == "I5": swe_manager = SweDataManager(var_name="SWE", path=obs_path) daily_obs = swe_manager.get_daily_clim_fields_interpolated_to( **obs_query_params) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean( [f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, n_agg_x=1, n_agg_y=1): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf(file_path=rconfig.data_path) # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) if vname == "TT": dates, vals_max = tmax_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to(start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) _, vals_min = tmin_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to(start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": daily_obs = pcp_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to(start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean([f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, obs_path=None): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf(file_path=rconfig.data_path) obs_query_params = dict( start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats ) # Calculate daily mean temperatures as T = (T(min) + T(max)) * 0.5 if vname == "TT": tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) # SWE elif vname == "I5": swe_manager = SweDataManager(var_name="SWE", path=obs_path) daily_obs = swe_manager.get_daily_clim_fields_interpolated_to(**obs_query_params) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean([f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def get_seasonal_clim_obs_data(rconfig=None, vname="TT", bmp_info=None, season_to_months=None, n_agg_x=1, n_agg_y=1): """ :param rconfig: :param vname: Corresponding model variable name i.e either TT or PR """ assert isinstance(rconfig, RunConfig) if season_to_months is None: season_to_months = DEFAULT_SEASON_TO_MONTHS if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf( file_path=rconfig.data_path) # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) if vname == "TT": dates, vals_max = tmax_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to( start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) _, vals_min = tmin_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to( start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": daily_obs = pcp_obs_manager.get_daily_clim_fields_aggregated_and_interpolated_to( start_year=rconfig.start_year, end_year=rconfig.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, n_agg_x=n_agg_x, n_agg_y=n_agg_y) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean( [f for d, f in zip(*daily_obs) if d.month in months], axis=0) return season_to_obs_data
def main(): season_to_months = DEFAULT_SEASON_TO_MONTHS r_config = RunConfig( data_path= "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5", start_year=1980, end_year=2010, label="CRCM5-L") bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) # Validate temperature and precip model_vars = ["TT", "PR"] # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) vname_to_obs_data = {} for vname in model_vars: if vname == "TT": dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to( start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to( start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to( start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean( [f for d, f in zip(*daily_obs) if d.month in months], axis=0) vname_to_obs_data[vname] = season_to_obs_data plot_all_vars_in_one_fig = True fig = None gs = None row_axes = None ncols = None if plot_all_vars_in_one_fig: plot_utils.apply_plot_params(font_size=12, width_pt=None, width_cm=25, height_cm=12) fig = plt.figure() ncols = len(season_to_months) + 1 gs = GridSpec(len(model_vars), ncols, width_ratios=(ncols - 1) * [ 1., ] + [ 0.05, ]) else: plot_utils.apply_plot_params(font_size=12, width_pt=None, width_cm=25, height_cm=25) row = 0 for mname in model_vars: if plot_all_vars_in_one_fig: row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols)] compare_vars(vname_model=mname, vname_to_obs=vname_to_obs_data, r_config=r_config, season_to_months=season_to_months, bmp_info_agg=bmp_info, axes_list=row_axes) row += 1 # Save the figure if necessary if plot_all_vars_in_one_fig: fig_path = img_folder.joinpath("{}.png".format("_".join(model_vars))) with fig_path.open("wb") as figfile: fig.savefig(figfile, format="png", bbox_inches="tight") plt.close(fig)
def plot_corr_fields_and_std(vname="TT", season_to_months=None, sim_config=None): """ :param vname: :param season_to_months: :param sim_config: """ bmp_info = analysis.get_basemap_info_from_hdf( file_path=sim_config.data_path) # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) season_to_corr = OrderedDict() season_to_area_mean_corr = OrderedDict() season_to_area_mean_std_diff = OrderedDict() season_to_area_mean_obs = OrderedDict() season_to_area_mean_model = OrderedDict() season_to_std_diff = OrderedDict() season_to_years = OrderedDict() # Convert modelled precip from M/s to mm/day if vname == "PR": model_convert_coef = 24 * 3600 * 1000 else: model_convert_coef = 1 years = None for season, months in season_to_months.items(): # Obs if vname == "TT": years, vals_max = tmax_obs_manager.get_seasonal_fields_interpolated_to( start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) _, vals_min = tmin_obs_manager.get_seasonal_fields_interpolated_to( start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) seasonal_obs = (years, (vals_min + vals_max) * 0.5) elif vname == "PR": seasonal_obs = pcp_obs_manager.get_seasonal_fields_interpolated_to( start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) years = seasonal_obs[0] else: raise Exception("Unknown variable: {}".format(vname)) season_to_years[season] = years # Model seasonal_model = analysis.get_mean_2d_fields_for_months( path=sim_config.data_path, var_name=vname, level=0, months=months, start_year=sim_config.start_year, end_year=sim_config.end_year) seasonal_model *= model_convert_coef # 2d fields season_to_corr[season] = stat_helpers.calculate_correlation_nd( seasonal_obs[1], seasonal_model) season_to_corr[season] = np.ma.masked_where( seasonal_obs[1][0, :, :].mask, season_to_corr[season]) i_arr, j_arr = np.where(~seasonal_obs[1][0, :, :].mask) season_to_std_diff[season] = np.ma.masked_all_like( seasonal_obs[1][0, :, :]) season_to_std_diff[season][ i_arr, j_arr] = (seasonal_model[:, i_arr, j_arr].std(axis=0) - seasonal_obs[1][:, i_arr, j_arr].std(axis=0) ) / seasonal_obs[1][:, i_arr, j_arr].std(axis=0) * 100 # area averages season_to_area_mean_obs[season] = seasonal_obs[1][:, i_arr, j_arr].mean(axis=1) season_to_area_mean_model[season] = seasonal_model[:, i_arr, j_arr].mean(axis=1) season_to_area_mean_corr[season] = np.corrcoef( season_to_area_mean_obs[season], season_to_area_mean_model[season])[0, 1] season_to_area_mean_std_diff[season] = ( season_to_area_mean_model[season].std() - season_to_area_mean_obs[season].std() ) / season_to_area_mean_obs[season].std() * 100 # plt.figure() # plt.plot(years, seasonal_obs[1][:, i_arr, j_arr].mean(axis=1), label="obs") # plt.plot(years, seasonal_model[:, i_arr, j_arr].mean(axis=1), label="model") # plt.legend() # # # plt.figure() # im = plt.pcolormesh(season_to_corr[season].T) # plt.colorbar(im) # plt.show() # plotting plot_utils.apply_plot_params(font_size=8, width_cm=23, height_cm=15) nrows = 3 gs = gridspec.GridSpec(nrows=nrows, ncols=len(season_to_months) + 1, width_ratios=[ 1, ] * len(season_to_months) + [ 0.05, ]) fig = plt.figure() xx, yy = bmp_info.get_proj_xy() clevs_corr = np.arange(-1, 1.1, 0.1) clevs_std_diff = np.arange(-100, 110, 10) cmap = "seismic" cmap_std = "seismic" cs_corr = None cs_std = None for col, season in enumerate(season_to_months): # Correlation fields row = 0 ax = fig.add_subplot(gs[row, col]) ax.set_title(season) if col == 0: pass # ax.set_ylabel("Correlation") cs_corr = bmp_info.basemap.contourf(xx, yy, season_to_corr[season], levels=clevs_corr, ax=ax, cmap=cmap) bmp_info.basemap.drawcoastlines(ax=ax) row += 1 ax = fig.add_subplot(gs[row, col]) if col == 0: pass # ax.set_ylabel(r"$\left( \sigma_{\rm model} - \sigma_{\rm obs.}\right)/\sigma_{\rm obs.} \cdot 100\%$") cs_std = bmp_info.basemap.contourf(xx, yy, season_to_std_diff[season], levels=clevs_std_diff, ax=ax, cmap=cmap_std, extend="both") bmp_info.basemap.drawcoastlines(ax=ax) # area average row += 1 ax = fig.add_subplot(gs[row, col]) if col == 0: ax.set_ylabel(varname_to_ts_label[vname]) ax.plot(season_to_years[season], season_to_area_mean_obs[season], "k", label="Obs.") ax.plot(season_to_years[season], season_to_area_mean_model[season], "r", label="Mod.") ax.set_title(r"$r=" + "{:.2f}, ".format(season_to_area_mean_corr[season]) + r" \varepsilon_{\sigma} = " + "{:.1f}".format(season_to_area_mean_std_diff[season]) + r" \% $") plt.setp(ax.xaxis.get_majorticklabels(), rotation=70) assert isinstance(ax, Axes) ax.xaxis.set_minor_locator(MultipleLocator()) ax.grid() if col == 0: ax.legend(loc="upper left") # add colorbars col = len(season_to_months) row = 0 ax = fig.add_subplot(gs[row, col]) plt.colorbar(cs_corr, cax=ax) row += 1 ax = fig.add_subplot(gs[row, col]) plt.colorbar(cs_std, cax=ax) from crcm5.analyse_hdf import common_plot_params fig.tight_layout() fig.savefig(os.path.join( img_folder, "{}_{}-{}_corr_std.png".format(vname, sim_config.start_year, sim_config.end_year)), bbox_inches="tight", dpi=common_plot_params.FIG_SAVE_DPI) plt.close(fig)
def draw_model_comparison(model_points=None, stations=None, sim_name_to_file_name=None, hdf_folder=None, start_year=None, end_year=None, cell_manager=None, stfl_name="STFA", drainage_area_reldiff_min=0.1, plot_upstream_area_averaged=True, sim_name_to_color=None): """ :param model_points: list of model point objects :param stations: list of stations corresponding to the list of model points :param cell_manager: is a CellManager instance which can be provided for better performance if necessary len(model_points) == len(stations) if stations is not None. if stations is None - then no measured streamflow will be plotted """ assert model_points is None or stations is None or len(stations) == len(model_points) label_list = list(sim_name_to_file_name.keys()) # Needed to keep the order the same for all subplots path0 = os.path.join(hdf_folder, list(sim_name_to_file_name.items())[0][1]) flow_directions = analysis.get_array_from_file(path=path0, var_name="flow_direction") lake_fraction = analysis.get_array_from_file(path=path0, var_name="lake_fraction") # mask lake fraction in the ocean lake_fraction = np.ma.masked_where((flow_directions <= 0) | (flow_directions > 128), lake_fraction) accumulation_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_ACCUMULATION_AREA_NAME) area_m2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_M2) # Try to read cell areas im meters if it is not Ok then try in km2 if area_m2 is not None: cell_area_km2 = area_m2 * 1.0e-6 else: cell_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_KM2) print("cell area ranges from {} to {}".format(cell_area_km2.min(), cell_area_km2.max())) # print "plotting from {0}".format(path0) # plt.pcolormesh(lake_fraction.transpose()) # plt.colorbar() # plt.show() # exit() file_scores = open("scores_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") file_correlations = open("corr_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") file_annual_discharge = open("flow_{0}_{1}-{2}.txt".format("_".join(label_list), start_year, end_year), "w") text_files = [file_scores, file_correlations, file_annual_discharge] # write the following columns to the scores file header_format = "{0:10s}\t{1:10s}\t{2:10s}\t" + "\t".join(["{" + str(i + 3) + ":10s}" for i in range(len(sim_name_to_file_name))]) line_format = "{0:10s}\t{1:10.1f}\t{2:10.1f}\t" + "\t".join(["{" + str(i + 3) + ":10.1f}" for i in range(len(sim_name_to_file_name))]) header_ns = ("ID", "DAo", "DAm",) + tuple(["NS({0})".format(key) for key in sim_name_to_file_name]) file_scores.write(header_format.format(*header_ns) + "\n") header_qyear = ("ID", "DAo", "DAm",) + tuple(["Qyear({0})".format(key) for key in label_list]) + \ ("Qyear(obs)",) header_format_qyear = header_format + "\t{" + str(len(label_list) + 3) + ":10s}" file_annual_discharge.write(header_format_qyear.format(*header_qyear) + "\n") lons2d, lats2d, basemap = analysis.get_basemap_from_hdf(file_path=path0) # Create a cell manager if it is not provided if cell_manager is None: cell_manager = CellManager(flow_directions, accumulation_area_km2=accumulation_area_km2, lons2d=lons2d, lats2d=lats2d) if stations is not None: # Get the list of the corresponding model points station_to_modelpoint = cell_manager.get_model_points_for_stations( station_list=stations, lake_fraction=lake_fraction, drainaige_area_reldiff_limit=drainage_area_reldiff_min) station_list = list(station_to_modelpoint.keys()) station_list.sort(key=lambda st1: st1.latitude, reverse=True) mp_list = [station_to_modelpoint[st] for st in station_list] else: mp_list = model_points station_list = None # sort so that the northernmost stations appear uppermost mp_list.sort(key=lambda mpt: mpt.latitude, reverse=True) # set ids to the model points so they can be distinguished easier model_point.set_model_point_ids(mp_list) # ###Uncomment the lines below for the validation plot in paper 2 # brewer2mpl.get_map args: set name set type number of colors # bmap = brewer2mpl.get_map("Set1", "qualitative", 9) # Change the default colors # mpl.rcParams["axes.color_cycle"] = bmap.mpl_colors # For the streamflow only plot ncols = 3 nrows = max(len(mp_list) // ncols, 1) if ncols * nrows < len(mp_list): nrows += 1 figure_stfl = plt.figure(figsize=(4 * ncols, 3 * nrows)) gs_stfl = gridspec.GridSpec(nrows=nrows, ncols=ncols) # a flag which signifies if a legend should be added to the plot, it is needed so we ahve only one legend per plot legend_added = False ax_stfl = None all_years = [y for y in range(start_year, end_year + 1)] if station_list is not None: processed_stations = station_list else: processed_stations = [None] * len(mp_list) processed_model_points = mp_list plot_point_positions_with_upstream_areas(processed_stations, processed_model_points, basemap, cell_manager, lake_fraction_field=lake_fraction) if plot_upstream_area_averaged: # create obs data managers anusplin_tmin = AnuSplinManager(variable="stmn") anusplin_tmax = AnuSplinManager(variable="stmx") anusplin_pcp = AnuSplinManager(variable="pcp") daily_dates, obs_tmin_fields = anusplin_tmin.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_tmax_fields = anusplin_tmax.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_pcp_fields = anusplin_pcp.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) swe_path = "/skynet3_rech1/huziy/swe_ross_brown/swe.nc4" if not os.path.isfile(os.path.realpath(swe_path)): raise IOError("SWE-obs file {} does not exist".format(swe_path)) swe_manager = SweDataManager(path=swe_path, var_name="SWE") obs_swe_daily_clim = swe_manager.get_daily_climatology(start_year, end_year) interpolated_obs_swe_clim = swe_manager.interpolate_daily_climatology_to(obs_swe_daily_clim, lons2d_target=lons2d, lats2d_target=lats2d) values_obs = None for i, the_model_point in enumerate(mp_list): ax_stfl = figure_stfl.add_subplot(gs_stfl[i // ncols, i % ncols], sharex=ax_stfl) assert isinstance(the_model_point, ModelPoint) # Check the number of years accessible for the station if the list of stations is given the_station = None if station_list is None else station_list[i] if the_station is not None: assert isinstance(the_station, Station) year_list = the_station.get_list_of_complete_years() year_list = list(filter(lambda yi: start_year <= yi <= end_year, year_list)) if len(year_list) < 1: continue else: year_list = all_years fig = plt.figure(figsize=(12, 15)) gs = gridspec.GridSpec(4, 4, wspace=1) # plot station position ax = fig.add_subplot(gs[3, 0:2]) upstream_mask = _plot_station_position(ax, the_station, basemap, cell_manager, the_model_point) # plot streamflows ax = fig.add_subplot(gs[0:2, 0:2]) dates = None model_daily_temp_clim = {} model_daily_precip_clim = {} model_daily_clim_surf_runoff = {} model_daily_clim_subsurf_runoff = {} model_daily_clim_swe = {} # get model data for the list of years simlabel_to_vals = {} for label in label_list: fname = sim_name_to_file_name[label] if hdf_folder is None: fpath = fname else: fpath = os.path.join(hdf_folder, fname) if plot_upstream_area_averaged: # read temperature data and calculate daily climatologic fileds _, model_daily_temp_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TT", level=0, start_year=start_year, end_year=end_year) # read modelled precip and calculate daily climatologic fields _, model_daily_precip_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="PR", level=0, start_year=start_year, end_year=end_year) # read modelled surface runoff and calculate daily climatologic fields _, model_daily_clim_surf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TRAF", level=0, start_year=start_year, end_year=end_year) # read modelled subsurface runoff and calculate daily climatologic fields _, model_daily_clim_subsurf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TDRA", level=0, start_year=start_year, end_year=end_year) # read modelled swe and calculate daily climatologic fields _, model_daily_clim_swe[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="I5", level=0, start_year=start_year, end_year=end_year) dates, values_model = analysis.get_daily_climatology_for_a_point(path=fpath, var_name=stfl_name, years_of_interest=year_list, i_index=the_model_point.ix, j_index=the_model_point.jy) ax.plot(dates, values_model, label=label, lw=2) if sim_name_to_color is None: ax_stfl.plot(dates, values_model, label=label, lw=2) else: ax_stfl.plot(dates, values_model, sim_name_to_color[label], label=label, lw=2) print(20 * "!!!") print("{} -> {}".format(label, sim_name_to_color[label])) print(20 * "!!!") simlabel_to_vals[label] = values_model if the_station is not None: assert isinstance(the_station, Station) dates, values_obs = the_station.get_daily_climatology_for_complete_years_with_pandas(stamp_dates=dates, years=year_list) # To keep the colors consistent for all the variables, the obs Should be plotted last ax.plot(dates, values_obs, label="Obs.", lw=2) # no ticklabels for streamflow plot plt.setp(ax.get_xticklabels(), visible=False) if sim_name_to_color is None: ax_stfl.plot(dates, values_obs, label="Obs.", lw=2) else: ax_stfl.plot(dates, values_obs, label="Obs.", lw=2, color=sim_name_to_color["Obs."]) # Print excesss from streamflow validation for label, values_model in simlabel_to_vals.items(): calclulate_spring_peak_err(dates, values_obs, values_model, st_id="{}: {}".format(label, the_station.id), da_mod=the_model_point.accumulation_area, da_obs=the_station.drainage_km2) ax.set_ylabel(r"Streamflow: ${\rm m^3/s}$") assert isinstance(ax, Axes) assert isinstance(fig, Figure) upstream_area_km2 = np.sum(cell_area_km2[upstream_mask == 1]) # Put some information about the point if the_station is not None: lf_upstream = lake_fraction[upstream_mask == 1] point_info = "{0}".format(the_station.id) write_annual_flows_to_txt(label_list, simlabel_to_vals, values_obs, file_annual_discharge, station_id=the_station.id, da_obs=the_station.drainage_km2, da_mod=the_model_point.accumulation_area) else: point_info = "{0}".format(the_model_point.point_id) ax.annotate(point_info, (0.8, 0.8), xycoords="axes fraction", bbox=dict(facecolor="white", alpha=0.5), va="top", ha="right") ax.legend(loc=(0.0, 1.05), borderaxespad=0, ncol=3) ax.xaxis.set_minor_formatter(FuncFormatter(lambda x, pos: num2date(x).strftime("%b")[0])) ax.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax.xaxis.set_major_locator(MonthLocator()) ax.grid() streamflow_axes = ax # save streamflow axes for later use if not legend_added: ax_stfl.legend(loc="lower left", bbox_to_anchor=(0, 1.15), borderaxespad=0, ncol=3) ax_stfl.xaxis.set_minor_formatter(FuncFormatter(lambda x, pos: num2date(x).strftime("%b")[0])) ax_stfl.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax_stfl.xaxis.set_major_locator(MonthLocator()) ax_stfl.set_ylabel(r"Streamflow ${\rm m^3/s}$") legend_added = True plt.setp(ax_stfl.get_xmajorticklabels(), visible=False) ax_stfl.yaxis.set_major_locator(MaxNLocator(nbins=5)) sfmt = ScalarFormatter(useMathText=True) sfmt.set_powerlimits((-2, 2)) ax_stfl.yaxis.set_major_formatter(sfmt) ax_stfl.grid() # annotate streamflow-only panel plot ax_stfl.annotate(point_info, (0.05, 0.95), xycoords="axes fraction", bbox=dict(facecolor="white"), va="top", ha="left") if plot_upstream_area_averaged: # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[3, 2:], sharex=streamflow_axes) _validate_temperature_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_tmin_clim_fields=obs_tmin_fields, obs_tmax_clim_fields=obs_tmax_fields, model_data_dict=model_daily_temp_clim, simlabel_list=label_list) # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[2, 2:], sharex=streamflow_axes) _validate_precip_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_precip_clim_fields=obs_pcp_fields, model_data_dict=model_daily_precip_clim, simlabel_list=label_list) # plot mean upstream surface runoff ax = fig.add_subplot(gs[0, 2:], sharex=streamflow_axes) _plot_upstream_surface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_surf_runoff, simlabel_list=label_list) # plot mean upstream subsurface runoff ax = fig.add_subplot(gs[1, 2:], sharex=streamflow_axes, sharey=ax) _plot_upstream_subsurface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_subsurf_runoff, simlabel_list=label_list) # plot mean upstream swe comparison ax = fig.add_subplot(gs[2, 0:2], sharex=streamflow_axes) print("Validating SWE for ", the_station.id, "--" * 20) _validate_swe_with_ross_brown(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_swe, obs_swe_clim_fields=interpolated_obs_swe_clim, simlabel_list=label_list) if the_station is not None: im_name = "comp_point_with_obs_{0}_{1}_{2}.png".format(the_station.id, the_station.source, "_".join(label_list)) im_folder_path = os.path.join(images_folder, the_station.source) else: im_name = "comp_point_with_obs_{0}_{1}.png".format(the_model_point.point_id, "_".join(label_list)) im_folder_path = os.path.join(images_folder, "outlets_point_comp") # create a folder for a given source of observed streamflow if it does not exist yet if not os.path.isdir(im_folder_path): os.mkdir(im_folder_path) im_path = os.path.join(im_folder_path, im_name) if plot_upstream_area_averaged: fig.savefig(im_path, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight", transparent=True) plt.close(fig) # return # temporary plot only one point assert isinstance(figure_stfl, Figure) figure_stfl.tight_layout() figure_stfl.savefig(os.path.join(images_folder, "comp_point_with_obs_{0}.png".format("_".join(label_list))), bbox_inches="tight", transparent=True, dpi=cpp.FIG_SAVE_DPI) plt.close(figure_stfl) # close information text files for f in text_files: f.close()
def plot_corr_fields_and_std(vname="TT", season_to_months=None, sim_config=None): """ :param vname: :param season_to_months: :param sim_config: """ bmp_info = analysis.get_basemap_info_from_hdf(file_path=sim_config.data_path) # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) season_to_corr = OrderedDict() season_to_area_mean_corr = OrderedDict() season_to_area_mean_std_diff = OrderedDict() season_to_area_mean_obs = OrderedDict() season_to_area_mean_model = OrderedDict() season_to_std_diff = OrderedDict() season_to_years = OrderedDict() # Convert modelled precip from M/s to mm/day if vname == "PR": model_convert_coef = 24 * 3600 * 1000 else: model_convert_coef = 1 years = None for season, months in season_to_months.items(): # Obs if vname == "TT": years, vals_max = tmax_obs_manager.get_seasonal_fields_interpolated_to(start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) _, vals_min = tmin_obs_manager.get_seasonal_fields_interpolated_to(start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) seasonal_obs = (years, (vals_min + vals_max) * 0.5) elif vname == "PR": seasonal_obs = pcp_obs_manager.get_seasonal_fields_interpolated_to(start_year=sim_config.start_year, end_year=sim_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats, months=months) years = seasonal_obs[0] else: raise Exception("Unknown variable: {}".format(vname)) season_to_years[season] = years # Model seasonal_model = analysis.get_mean_2d_fields_for_months(path=sim_config.data_path, var_name=vname, level=0, months=months, start_year=sim_config.start_year, end_year=sim_config.end_year) seasonal_model *= model_convert_coef # 2d fields season_to_corr[season] = stat_helpers.calculate_correlation_nd(seasonal_obs[1], seasonal_model) season_to_corr[season] = np.ma.masked_where(seasonal_obs[1][0, :, :].mask, season_to_corr[season]) i_arr, j_arr = np.where(~seasonal_obs[1][0, :, :].mask) season_to_std_diff[season] = np.ma.masked_all_like(seasonal_obs[1][0, :, :]) season_to_std_diff[season][i_arr, j_arr] = (seasonal_model[:, i_arr, j_arr].std(axis=0) - seasonal_obs[1][:, i_arr, j_arr].std(axis=0)) / seasonal_obs[1][:, i_arr, j_arr].std(axis=0) * 100 # area averages season_to_area_mean_obs[season] = seasonal_obs[1][:, i_arr, j_arr].mean(axis=1) season_to_area_mean_model[season] = seasonal_model[:, i_arr, j_arr].mean(axis=1) season_to_area_mean_corr[season] = np.corrcoef(season_to_area_mean_obs[season], season_to_area_mean_model[season])[0, 1] season_to_area_mean_std_diff[season] = (season_to_area_mean_model[season].std() - season_to_area_mean_obs[season].std()) / season_to_area_mean_obs[season].std() * 100 # plt.figure() # plt.plot(years, seasonal_obs[1][:, i_arr, j_arr].mean(axis=1), label="obs") # plt.plot(years, seasonal_model[:, i_arr, j_arr].mean(axis=1), label="model") # plt.legend() # # # plt.figure() # im = plt.pcolormesh(season_to_corr[season].T) # plt.colorbar(im) # plt.show() # plotting plot_utils.apply_plot_params(font_size=8, width_cm=23, height_cm=15) nrows = 3 gs = gridspec.GridSpec(nrows=nrows, ncols=len(season_to_months) + 1, width_ratios=[1, ] * len(season_to_months) + [0.05, ]) fig = plt.figure() xx, yy = bmp_info.get_proj_xy() clevs_corr = np.arange(-1, 1.1, 0.1) clevs_std_diff = np.arange(-100, 110, 10) cmap = "seismic" cmap_std = "seismic" cs_corr = None cs_std = None for col, season in enumerate(season_to_months): # Correlation fields row = 0 ax = fig.add_subplot(gs[row, col]) ax.set_title(season) if col == 0: pass # ax.set_ylabel("Correlation") cs_corr = bmp_info.basemap.contourf(xx, yy, season_to_corr[season], levels=clevs_corr, ax=ax, cmap=cmap) bmp_info.basemap.drawcoastlines(ax=ax) row += 1 ax = fig.add_subplot(gs[row, col]) if col == 0: pass # ax.set_ylabel(r"$\left( \sigma_{\rm model} - \sigma_{\rm obs.}\right)/\sigma_{\rm obs.} \cdot 100\%$") cs_std = bmp_info.basemap.contourf(xx, yy, season_to_std_diff[season], levels=clevs_std_diff, ax=ax, cmap=cmap_std, extend="both") bmp_info.basemap.drawcoastlines(ax=ax) # area average row += 1 ax = fig.add_subplot(gs[row, col]) if col == 0: ax.set_ylabel(varname_to_ts_label[vname]) ax.plot(season_to_years[season], season_to_area_mean_obs[season], "k", label="Obs.") ax.plot(season_to_years[season], season_to_area_mean_model[season], "r", label="Mod.") ax.set_title(r"$r=" + "{:.2f}, ".format(season_to_area_mean_corr[season]) + r" \varepsilon_{\sigma} = " + "{:.1f}".format(season_to_area_mean_std_diff[season]) + r" \% $") plt.setp(ax.xaxis.get_majorticklabels(), rotation=70) assert isinstance(ax, Axes) ax.xaxis.set_minor_locator(MultipleLocator()) ax.grid() if col == 0: ax.legend(loc="upper left") # add colorbars col = len(season_to_months) row = 0 ax = fig.add_subplot(gs[row, col]) plt.colorbar(cs_corr, cax=ax) row += 1 ax = fig.add_subplot(gs[row, col]) plt.colorbar(cs_std, cax=ax) from crcm5.analyse_hdf import common_plot_params fig.tight_layout() fig.savefig(os.path.join(img_folder, "{}_{}-{}_corr_std.png".format(vname, sim_config.start_year, sim_config.end_year)), bbox_inches="tight", dpi=common_plot_params.FIG_SAVE_DPI) plt.close(fig)
def main(): season_to_months = DEFAULT_SEASON_TO_MONTHS r_config = RunConfig( data_path="/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5", start_year=1980, end_year=2010, label="CRCM5-L" ) bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) # Validate temperature and precip model_vars = ["TT", "PR"] # Get Anusplin data managers obs_path = "/home/huziy/skynet3_rech1/anusplin_links" pcp_obs_manager = AnuSplinManager(variable="pcp", folder_path=obs_path) tmax_obs_manager = AnuSplinManager(variable="stmx", folder_path=obs_path) tmin_obs_manager = AnuSplinManager(variable="stmn", folder_path=obs_path) vname_to_obs_data = {} for vname in model_vars: if vname == "TT": dates, vals_max = tmax_obs_manager.get_daily_clim_fields_interpolated_to(start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) _, vals_min = tmin_obs_manager.get_daily_clim_fields_interpolated_to(start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) daily_obs = (dates, (vals_min + vals_max) * 0.5) elif vname == "PR": daily_obs = pcp_obs_manager.get_daily_clim_fields_interpolated_to(start_year=r_config.start_year, end_year=r_config.end_year, lons_target=bmp_info.lons, lats_target=bmp_info.lats) else: raise Exception("Unknown variable: {}".format(vname)) season_to_obs_data = OrderedDict() for season, months in season_to_months.items(): season_to_obs_data[season] = np.mean([f for d, f in zip(*daily_obs) if d.month in months], axis=0) vname_to_obs_data[vname] = season_to_obs_data plot_all_vars_in_one_fig = True fig = None gs = None row_axes = None ncols = None if plot_all_vars_in_one_fig: plot_utils.apply_plot_params(font_size=12, width_pt=None, width_cm=25, height_cm=12) fig = plt.figure() ncols = len(season_to_months) + 1 gs = GridSpec(len(model_vars), ncols, width_ratios=(ncols - 1) * [1., ] + [0.05, ]) else: plot_utils.apply_plot_params(font_size=12, width_pt=None, width_cm=25, height_cm=25) row = 0 for mname in model_vars: if plot_all_vars_in_one_fig: row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols)] compare_vars(vname_model=mname, vname_to_obs=vname_to_obs_data, r_config=r_config, season_to_months=season_to_months, bmp_info_agg=bmp_info, axes_list=row_axes) row += 1 # Save the figure if necessary if plot_all_vars_in_one_fig: fig_path = img_folder.joinpath("{}.png".format("_".join(model_vars))) with fig_path.open("wb") as figfile: fig.savefig(figfile, format="png", bbox_inches="tight") plt.close(fig)
def do_4_seasons(start_year=1980, end_year=2010): # Creates one file per simulation containing biases for 4 seasons season_to_months = { "Winter": [12, 1, 2], "Spring": list(range(3, 6)), # "Summer": list(range(6, 9)), # "Fall": list(range(9, 11)) } season_to_plot_indices = { "Winter": (0, 0), "Spring": (0, 1), "Summer": (1, 0), "Fall": (1, 1) } simlabel_to_path = { # "CRCM5-R-CanESM2-current": "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-r-cc-canesm2-1980-2010.hdf5", # "CRCM5-R": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-r.hdf5", "CRCM5-NL": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-r.hdf5", "CRCM5-L1": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-r.hdf5", # "CRCM5-HCD-RL-INTFL-ECOCLIMAP": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl-intfl_spinup_ecoclimap.hdf", # "CRCM5-HCD-RL-INTFL-ECOCLIMAP-ERA075": "/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl-intfl_spinup_ecoclimap_era075.hdf" # "CRCM5-L-CanESM2": "/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5" } print("Period of interest: {0}-{1}".format(start_year, end_year)) lake_fraction = analysis.get_array_from_file( list(simlabel_to_path.items())[-1][1], var_name=infovar.HDF_LAKE_FRACTION_NAME) pcp_obs_manager = AnuSplinManager(variable="pcp") tmax_obs_manager = AnuSplinManager(variable="stmx") tmin_obs_manager = AnuSplinManager(variable="stmn") tmax_obs_manager = None tmin_obs_manager = None swe_obs_manager = SweDataManager(var_name="SWE") station_ids = ["104001", "093806", "093801", "081002", "081007", "080718"] for simlabel, path in simlabel_to_path.items(): # Validate precipitations validate_precip(model_file=path, obs_manager=pcp_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, station_ids_list=station_ids) # # # Validate daily maximum temperature validate_temperature(model_file=path, obs_manager=tmax_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, model_var_name="TT_max") validate_temperature(model_file=path, obs_manager=tmin_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, model_var_name="TT_min") # validate swe validate_swe(model_file=path, obs_manager=swe_obs_manager, season_to_months=season_to_months, simlabel=simlabel, season_to_plot_indices=season_to_plot_indices, start_year=start_year, end_year=end_year, lake_fraction=lake_fraction, station_ids_list=station_ids)
def draw_model_comparison(model_points=None, stations=None, sim_name_to_file_name=None, hdf_folder=None, start_year=None, end_year=None, cell_manager=None, plot_upstream_averages=True): """ :param model_points: list of model point objects :param stations: list of stations corresponding to the list of model points :param cell_manager: is a CellManager instance which can be provided for better performance if necessary len(model_points) == len(stations) if stations is not None. if stations is None - then no measured streamflow will be plotted """ assert model_points is None or stations is None or len(stations) == len(model_points) path0 = os.path.join(hdf_folder, list(sim_name_to_file_name.items())[0][1]) flow_directions = analysis.get_array_from_file(path=path0, var_name="flow_direction") lake_fraction = analysis.get_array_from_file(path=path0, var_name="lake_fraction") accumulation_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_ACCUMULATION_AREA_NAME) cell_area_km2 = analysis.get_array_from_file(path=path0, var_name=infovar.HDF_CELL_AREA_NAME_M2) # print "plotting from {0}".format(path0) # plt.pcolormesh(lake_fraction.transpose()) # plt.colorbar() # plt.show() # exit() file_scores = open( "scores_{0}_{1}-{2}.txt".format("_".join(list(sim_name_to_file_name.keys())), start_year, end_year), "w") # write the following columns to the scores file header_format = "{0:10s}\t{1:10s}\t{2:10s}\t" + "\t".join(["{" + str(i + 3) + ":10s}" for i in range(len(sim_name_to_file_name))]) line_format = "{0:10s}\t{1:10.1f}\t{1:10.1f}\t" + "\t".join(["{" + str(i + 3) + ":10.1f}" for i in range(len(sim_name_to_file_name))]) header = ("ID", "DAo", "DAm",) + tuple(["NS({0})".format(key) for key in sim_name_to_file_name]) file_scores.write(header_format.format(*header) + "\n") lons2d, lats2d, basemap = analysis.get_basemap_from_hdf(file_path=path0) # Create a cell manager if it is not provided if cell_manager is None: cell_manager = CellManager(flow_directions, accumulation_area_km2=accumulation_area_km2, lons2d=lons2d, lats2d=lats2d) if stations is not None: # Get the list of the corresponding model points station_to_modelpoint_list = cell_manager.get_lake_model_points_for_stations(station_list=stations, lake_fraction=lake_fraction, nneighbours=1) station_list = list(station_to_modelpoint_list.keys()) station_list.sort(key=lambda st1: st1.latitude, reverse=True) processed_stations = station_list else: mp_list = model_points station_list = None # sort so that the northernmost stations appear uppermost mp_list.sort(key=lambda mpt: mpt.latitude, reverse=True) # set ids to the model points so they can be distinguished easier model_point.set_model_point_ids(mp_list) processed_stations = mp_list station_to_modelpoint_list = {} # brewer2mpl.get_map args: set name set type number of colors bmap = brewer2mpl.get_map("Set1", "qualitative", 9) # Change the default colors mpl.rcParams["axes.color_cycle"] = bmap.mpl_colors # For the streamflow only plot ncols = 3 nrows = max(len(station_to_modelpoint_list) // ncols, 1) if ncols * nrows < len(station_to_modelpoint_list): nrows += 1 figure_panel = plt.figure() gs_panel = gridspec.GridSpec(nrows=nrows + 1, ncols=ncols) # a flag which signifies if a legend should be added to the plot, it is needed so we ahve only one legend per plot legend_added = False label_list = list(sim_name_to_file_name.keys()) # Needed to keep the order the same for all subplots all_years = [y for y in range(start_year, end_year + 1)] # processed_model_points = mp_list # plot_point_positions_with_upstream_areas(processed_stations, processed_model_points, basemap, cell_manager) if plot_upstream_averages: # create obs data managers anusplin_tmin = AnuSplinManager(variable="stmn") anusplin_tmax = AnuSplinManager(variable="stmx") anusplin_pcp = AnuSplinManager(variable="pcp") daily_dates, obs_tmin_fields = anusplin_tmin.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_tmax_fields = anusplin_tmax.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) _, obs_pcp_fields = anusplin_pcp.get_daily_clim_fields_interpolated_to( start_year=start_year, end_year=end_year, lons_target=lons2d, lats_target=lats2d) swe_manager = SweDataManager(var_name="SWE") obs_swe_daily_clim = swe_manager.get_daily_climatology(start_year, end_year) interpolated_obs_swe_clim = swe_manager.interpolate_daily_climatology_to(obs_swe_daily_clim, lons2d_target=lons2d, lats2d_target=lats2d) # clear the folder with images (to avoid confusion of different versions) _remove_previous_images(processed_stations[0]) ax_panel = figure_panel.add_subplot(gs_panel[0, :]) plot_positions_of_station_list(ax_panel, station_list, [station_to_modelpoint_list[s][0] for s in station_list], basemap=basemap, cell_manager=cell_manager, fill_upstream_areas=False) ax_to_share = None for i, the_station in enumerate(station_list): # +1 due to the plot with station positions ax_panel = figure_panel.add_subplot(gs_panel[1 + i // ncols, i % ncols], sharex=ax_to_share) if ax_to_share is None: ax_to_share = ax_panel # Check the number of years accessible for the station if the list of stations is given if the_station is not None: assert isinstance(the_station, Station) year_list = the_station.get_list_of_complete_years() year_list = list(filter(lambda yi: start_year <= yi <= end_year, year_list)) if len(year_list) < 1: continue print("Working on station: {0}".format(the_station.id)) else: year_list = all_years fig = plt.figure() gs = gridspec.GridSpec(4, 4, wspace=1) # plot station position ax = fig.add_subplot(gs[3, 0:2]) upstream_mask = _plot_station_position(ax, the_station, basemap, cell_manager, station_to_modelpoint_list[the_station][0]) # plot streamflows ax = fig.add_subplot(gs[0:2, 0:2]) dates = None model_daily_temp_clim = {} model_daily_precip_clim = {} model_daily_clim_surf_runoff = {} model_daily_clim_subsurf_runoff = {} model_daily_clim_swe = {} model_daily_clim_evap = {} # get model data for the list of years for label in label_list: fname = sim_name_to_file_name[label] fpath = os.path.join(hdf_folder, fname) if plot_upstream_averages: # read temperature data and calculate daily climatologic fileds dates, model_daily_temp_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TT", level=1, start_year=start_year, end_year=end_year) # read modelled precip and calculate daily climatologic fields _, model_daily_precip_clim[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="PR", level=None, start_year=start_year, end_year=end_year) # read modelled surface runoff and calculate daily climatologic fields _, model_daily_clim_surf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TRAF", level=1, start_year=start_year, end_year=end_year) # read modelled subsurface runoff and calculate daily climatologic fields _, model_daily_clim_subsurf_runoff[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="TDRA", level=1, start_year=start_year, end_year=end_year) # read modelled swe and calculate daily climatologic fields _, model_daily_clim_swe[label] = analysis.get_daily_climatology( path_to_hdf_file=fpath, var_name="I5", level=None, start_year=start_year, end_year=end_year) values_model = None # lake level due to evap/precip values_model_evp = None lf_total = 0 for the_model_point in station_to_modelpoint_list[the_station]: if the_model_point.lake_fraction is None: mult = 1.0 else: mult = the_model_point.lake_fraction lf_total += mult # Calculate lake depth variation for this simulation, since I forgot to uncomment it in the model if label.lower() != "crcm5-hcd-r": assert isinstance(the_model_point, ModelPoint) _, temp = analysis.get_daily_climatology_for_a_point(path=fpath, var_name="CLDP", years_of_interest=year_list, i_index=the_model_point.ix, j_index=the_model_point.jy) if values_model is None: values_model = mult * np.asarray(temp) else: values_model = mult * np.asarray(temp) + values_model else: raise NotImplementedError("Cannot handle lake depth for {0}".format(label)) if label.lower() in ["crcm5-hcd-rl", "crcm5-l2"]: dates, temp = analysis.get_daily_climatology_for_a_point_cldp_due_to_precip_evap( path=fpath, i_index=the_model_point.ix, j_index=the_model_point.jy, year_list=year_list, point_label=the_station.id) if values_model_evp is None: values_model_evp = mult * np.asarray(temp) else: values_model_evp = mult * np.asarray(temp) + values_model_evp values_model /= float(lf_total) values_model = values_model - np.mean(values_model) print("lake level anomaly ranges for {0}:{1:.8g};{2:.8g}".format(label, values_model.min(), values_model.max())) ax.plot(dates, values_model, label=label, lw=2) ax_panel.plot(dates, values_model, label=label, lw=2) if values_model_evp is not None: # normalize cldp values_model_evp /= float(lf_total) # convert to m/s values_model_evp /= 1000.0 values_model_evp = values_model_evp - np.mean(values_model_evp) ax.plot(dates, values_model_evp, label=label + "(P-E)", lw=2) ax_panel.plot(dates, values_model_evp, label=label + "(P-E)", lw=2) if the_station is not None: print(type(dates[0])) dates, values_obs = the_station.get_daily_climatology_for_complete_years_with_pandas(stamp_dates=dates, years=year_list) # To keep the colors consistent for all the variables, the obs Should be plotted last ax.plot(dates, values_obs - np.mean(values_obs), label="Obs.", lw=2, color="k") ax_panel.plot(dates, values_obs - np.mean(values_obs), label="Obs.", lw=2, color="k") # calculate nash sutcliff coefficient and skip if too small ax.set_ylabel(r"Level variation: (${\rm m}$)") assert isinstance(ax, Axes) assert isinstance(fig, Figure) upstream_area_km2 = np.sum(cell_area_km2[upstream_mask == 1]) # Put some information about the point if the_station is not None: point_info = "{0}".format(the_station.id) else: point_info = "{0}".format(the_model_point.point_id) ax.annotate(point_info, (0.9, 0.9), xycoords="axes fraction", bbox=dict(facecolor="white")) ax_panel.annotate(point_info, (0.96, 0.96), xycoords="axes fraction", bbox=dict(facecolor="white"), va="top", ha="right") ax.legend(loc=(0.0, 1.05), borderaxespad=0, ncol=3) ax.xaxis.set_major_formatter(FuncFormatter(lambda val, pos: num2date(val).strftime("%b")[0])) # ax.xaxis.set_minor_locator(MonthLocator()) ax.xaxis.set_major_locator(MonthLocator()) ax.grid() streamflow_axes = ax # save streamflow axes for later use if not legend_added: ax_panel.legend(loc=(0.0, 1.1), borderaxespad=0.5, ncol=1) ax_panel.xaxis.set_minor_formatter(FuncFormatter(lambda val, pos: num2date(val).strftime("%b")[0])) ax_panel.xaxis.set_minor_locator(MonthLocator(bymonthday=15)) ax_panel.xaxis.set_major_locator(MonthLocator()) ax_panel.xaxis.set_major_formatter(FuncFormatter(lambda val, pos: "")) ax_panel.set_ylabel(r"Level variation (${\rm m}$)") legend_added = True ax_panel.yaxis.set_major_locator(MaxNLocator(nbins=5)) ax_panel.grid() if plot_upstream_averages: # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[3, 2:], sharex=streamflow_axes) success = _validate_temperature_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_tmin_clim_fields=obs_tmin_fields, obs_tmax_clim_fields=obs_tmax_fields, model_data_dict=model_daily_temp_clim, simlabel_list=label_list) # plot temperature comparisons (tmod - daily with anusplin tmin and tmax) ax = fig.add_subplot(gs[2, 2:], sharex=streamflow_axes) _validate_precip_with_anusplin(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, obs_precip_clim_fields=obs_pcp_fields, model_data_dict=model_daily_precip_clim, simlabel_list=label_list) # plot mean upstream surface runoff ax = fig.add_subplot(gs[0, 2:], sharex=streamflow_axes) _plot_upstream_surface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_surf_runoff, simlabel_list=label_list) # plot mean upstream subsurface runoff ax = fig.add_subplot(gs[1, 2:], sharex=streamflow_axes, sharey=ax) _plot_upstream_subsurface_runoff(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_subsurf_runoff, simlabel_list=label_list) # plot mean upstream swe comparison ax = fig.add_subplot(gs[2, 0:2], sharex=streamflow_axes) _validate_swe_with_ross_brown(ax, the_model_point, cell_area_km2=cell_area_km2, upstream_mask=upstream_mask, daily_dates=daily_dates, model_data_dict=model_daily_clim_swe, obs_swe_clim_fields=interpolated_obs_swe_clim, simlabel_list=label_list) if the_station is not None: im_name = "comp_point_with_obs_{0}_{1}_{2}.pdf".format(the_station.id, the_station.source, "_".join(label_list)) im_folder_path = os.path.join(images_folder, the_station.source + "_levels") else: im_name = "comp_point_with_obs_{0}_{1}.pdf".format(the_model_point.point_id, "_".join(label_list)) im_folder_path = os.path.join(images_folder, "outlets_point_comp_levels") # create a folder for a given source of observed streamflow if it does not exist yet if not os.path.isdir(im_folder_path): os.mkdir(im_folder_path) im_path = os.path.join(im_folder_path, im_name) if plot_upstream_averages: fig.savefig(im_path, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight") plt.close(fig) assert isinstance(figure_panel, Figure) figure_panel.tight_layout() figure_panel.savefig( os.path.join(images_folder, "comp_lake-levels_at_point_with_obs_{0}.png".format("_".join(label_list))), bbox_inches="tight") plt.close(figure_panel) file_scores.close()