def main(): import application_properties application_properties.set_current_directory() # Create folder for output images if not img_folder.is_dir(): img_folder.mkdir(parents=True) rea_driven_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5" rea_driven_label = "ERAI-CRCM5-L" gcm_driven_path = "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5" gcm_driven_label = "CanESM2-CRCM5-L" start_year_c = 1980 end_year_c = 2010 varname = "STFL" params = dict( data_path=rea_driven_path, start_year=start_year_c, end_year=end_year_c, label=rea_driven_label) geo_data_file = "/skynet3_rech1/huziy/hdf_store/pm1979010100_00000000p" rea_driven_config = RunConfig(**params) params.update(dict(data_path=gcm_driven_path, label=gcm_driven_label)) gcm_driven_config = RunConfig(**params) r_obj = RPN(geo_data_file) facc = r_obj.get_first_record_for_name("FAA") fldr = r_obj.get_first_record_for_name("FLDR") lkfr = r_obj.get_first_record_for_name("ML") bmp_info = analysis.get_basemap_info_from_hdf(file_path=rea_driven_path) basin_name_to_out_indices_map, basin_name_to_basin_mask = get_basin_to_outlet_indices_map(bmp_info=bmp_info, accumulation_areas=facc, directions=fldr, lake_fraction_field=lkfr) # select lake rich basins sel_basins = ["ARN", "PYR", "LGR", "RDO", "SAG", "WAS"] basin_name_to_out_indices_map = {k: v for k, v in basin_name_to_out_indices_map.items() if k in sel_basins} rea_driven_daily = analysis.get_daily_climatology_for_rconf(rea_driven_config, var_name=varname, level=0) gcm_driven_daily = analysis.get_daily_climatology_for_rconf(gcm_driven_config, var_name=varname, level=0) rea_driven_config.data_daily = rea_driven_daily gcm_driven_config.data_daily = gcm_driven_daily plot_comparison_hydrographs(basin_name_to_out_indices_map, rea_config=rea_driven_config, gcm_config=gcm_driven_config)
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=2009, label="CRCM5-L" ) # Number of points for aggregation nx_agg = 5 ny_agg = 5 bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) bmp_info_agg = bmp_info.get_aggregated(nagg_x=nx_agg, nagg_y=ny_agg) # Validate temperature and precip model_vars = ["TT", "PR"] obs_vars = ["tmp", "pre"] obs_paths = [ "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.tmp.dat.nc", "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.pre.dat.nc" ] 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, oname, opath in zip(model_vars, obs_vars, obs_paths): 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_obs=oname, r_config=r_config, season_to_months=season_to_months, nx_agg=nx_agg, ny_agg=ny_agg, bmp_info_agg=bmp_info_agg, obs_path=opath, diff_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 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(): from crcm5.analyse_hdf import do_analysis_using_pytables as analysis import application_properties application_properties.set_current_directory() # define the region of interest using indices sel = Selection(start_i=30, start_j=50, ni=40, nj=40) start_year = 1991 end_year = 2010 # Labels and paths to the data label_base = "CRCM5-NL" path_base = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-r.hdf5" labels = ["CRCM5-L1"] paths = ["/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-r.hdf5"] bmp_info = analysis.get_basemap_info_from_hdf(file_path=path_base) # Do the calculations # Do the plotting fig = plt.figure() gs = GridSpec(2, 2) # Plot the domain ax = fig.add_subplot(gs[0, :]) assert isinstance(ax, Axes) bmp_info.basemap.drawcoastlines(ax=ax) xx, yy = bmp_info.get_proj_xy() # add the region of interest to the map ll_i, ll_j = sel.ll_indices() ur_i, ur_j = sel.ur_indices() coords = ((ll_i, ll_j), (ll_i, ur_j), (ur_i, ur_j), (ur_i, ll_j)) coords = [(xx[i, j], yy[i, j]) for (i, j) in coords] coords = np.array(coords) ax.add_patch(Polygon(coords, facecolor="none", linewidth=3)) plt.show()
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, obs_path=None): # Number of points for aggregation """ return aggregated BasemapInfo object corresponding to the CRU resolution :param rconfig: :param vname: :param bmp_info: BasemapInfo object for the model field (will be upscaled to the CRU resolution) :param season_to_months: """ nx_agg = 5 ny_agg = 5 if bmp_info is None: bmp_info = analysis.get_basemap_info_from_hdf(file_path=rconfig.data_path) bmp_info_agg = bmp_info.get_aggregated(nagg_x=nx_agg, nagg_y=ny_agg) # Validate temperature and precip model_vars = ["TT", "PR"] obs_vars = ["tmp", "pre"] obs_paths = [ "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.tmp.dat.nc", "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.pre.dat.nc" ] model_var_to_obs_var = dict(zip(model_vars, obs_vars)) model_var_to_obs_path = dict(zip(model_vars, obs_paths)) if obs_path is None: obs_path = model_var_to_obs_path[vname] cru = CRUDataManager(var_name=model_var_to_obs_var[vname], path=obs_path) seasonal_clim_fields_obs = cru.get_seasonal_means(season_name_to_months=season_to_months, start_year=rconfig.start_year, end_year=rconfig.end_year) seasonal_clim_fields_obs_interp = OrderedDict() for season, cru_field in seasonal_clim_fields_obs.items(): seasonal_clim_fields_obs_interp[season] = cru.interpolate_data_to(cru_field, lons2d=bmp_info_agg.lons, lats2d=bmp_info_agg.lats, nneighbours=1) # assert hasattr(seasonal_clim_fields_obs_interp[season], "mask") return bmp_info_agg, seasonal_clim_fields_obs_interp
def main(): import application_properties application_properties.set_current_directory() plot_utils.apply_plot_params(font_size=12, width_cm=25, height_cm=25) # Create folder for output images if not img_folder.is_dir(): img_folder.mkdir(parents=True) with_lakes_c_path = "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5" with_lakes_label = "CRCM5-L" no_lakes_c_path = "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-r-cc-canesm2-1980-2010.hdf5" no_lakes_label = "CRCM5-NL" start_year_c = 1980 end_year_c = 2010 varname = "STFL" nyears_to_future = 75 with_lakes_config_c = RunConfig(data_path=with_lakes_c_path, start_year=start_year_c, end_year=end_year_c, label=with_lakes_label) with_lakes_config_f = with_lakes_config_c.get_shifted_config(nyears_to_future) no_lakes_config_c = RunConfig(data_path=no_lakes_c_path, start_year=start_year_c, end_year=end_year_c, label=no_lakes_label) no_lakes_config_f = no_lakes_config_c.get_shifted_config(nyears_to_future) bmp_info = analysis.get_basemap_info_from_hdf(file_path=with_lakes_c_path) # Calculate daily climatologic fields with_lakes_c_daily = analysis.get_daily_climatology_for_rconf(with_lakes_config_c, var_name=varname, level=0) with_lakes_f_daily = analysis.get_daily_climatology_for_rconf(with_lakes_config_f, var_name=varname, level=0) no_lakes_c_daily = analysis.get_daily_climatology_for_rconf(no_lakes_config_c, var_name=varname, level=0) no_lakes_f_daily = analysis.get_daily_climatology_for_rconf(no_lakes_config_f, var_name=varname, level=0) configs = DataConfig(bmp_info, no_lakes_config_c, no_lakes_config_f, with_lakes_config_c, with_lakes_config_f) args = (no_lakes_c_daily, no_lakes_f_daily, with_lakes_c_daily, with_lakes_f_daily) data = Data(*[arg[1] for arg in args]) plot_comparison_std(configs, data, varname=varname)
def main(): pf_mask_file = "pf_mask_qc0.1deg.220x220.nc" if not os.path.isfile(pf_mask_file): path_to_rpn_with_targ_grid = "/RESCUE/skynet3_rech1/huziy/from_guillimin/new_outputs/current_climate_30_yr_sims/quebec_0.1_crcm5-hcd-rl-intfl_ITFS/Samples/quebec_crcm5-hcd-rl-intfl_197901/pm1979010100_00008928p" save_pf_mask_to_netcdf(pf_mask_file, path_to_rpn_with_target_grid=path_to_rpn_with_targ_grid) with Dataset(pf_mask_file) as ds: pf_mask = ds.variables["pf_type"][:] print(ds.variables.keys()) lay_widths = qc01deg_sim_layer_widths data_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl-intfl_ITFS.hdf5" start_year = 1990 end_year = 1990 alt_field = do_calculations(data_path=data_path, lay_widths=lay_widths, start_year=start_year, end_year=end_year) alt_field = np.ma.masked_where((alt_field < 0) | (alt_field > 8), alt_field) # do the plotting plot_utils.apply_plot_params() fig = plt.figure() bmp_info = analysis.get_basemap_info_from_hdf(file_path=data_path) # Mask oceans alt_field = maskoceans(bmp_info.lons, bmp_info.lats, alt_field) alt_field = np.ma.masked_where((pf_mask > 2) | (pf_mask < 1), alt_field) alt_field[(pf_mask == 2) & (~alt_field.mask)] = 5.5 xx, yy = bmp_info.get_proj_xy() img = bmp_info.basemap.contourf(xx, yy, alt_field, extend="both") bmp_info.basemap.colorbar(img) bmp_info.basemap.drawcoastlines() plt.contour(xx, yy, pf_mask, levels=[1, 2, 3], colors="k", linewidth=2) fig_path = "{}_alt_{}-{}.png".format(data_path[:-5], start_year, end_year) fig.savefig(fig_path, transparent=True, dpi=common_plot_params.FIG_SAVE_DPI, bbox_inches="tight") print("Saving the plot to {}".format(fig_path)) plt.show()
def main(): import application_properties application_properties.set_current_directory() # Create folder for output images if not img_folder.is_dir(): img_folder.mkdir(parents=True) rea_driven_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5" rea_driven_label = "CRCM5-L-ERAI" # gcm_driven_path_c = "/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-r-cc-canesm2-1980-2010.hdf5" gcm_driven_path_c = "/home/huziy/skynet3_rech1/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5" gcm_driven_label_c = "CRCM5-L" gcm_driven_path_f = "/home/huziy/skynet3_rech1/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-2070-2100.hdf5" start_year_c = 1980 end_year_c = 2010 varname = "STFL" future_shift_years = 90 params = dict( data_path=rea_driven_path, start_year=start_year_c, end_year=end_year_c, label=rea_driven_label) geo_data_file = "/skynet3_rech1/huziy/hdf_store/pm1979010100_00000000p" rea_driven_config = RunConfig(**params) params.update(dict(data_path=gcm_driven_path_c, label=gcm_driven_label_c)) gcm_driven_config_c = RunConfig(**params) gcm_driven_config_f = gcm_driven_config_c.get_shifted_config(shift_years=future_shift_years, data_path=gcm_driven_path_f) r_obj = RPN(geo_data_file) facc = r_obj.get_first_record_for_name("FAA") fldr = r_obj.get_first_record_for_name("FLDR") lkfr = r_obj.get_first_record_for_name("ML") # get basemap information bmp_info = analysis.get_basemap_info_from_hdf(file_path=rea_driven_path) # get basin mask _, bname_to_mask = plot_basin_outlets(bmp_info=bmp_info, directions=fldr, accumulation_areas=facc, lake_fraction_field=lkfr) all_basins_mask = np.zeros(fldr.shape) for bname, the_mask in bname_to_mask.items(): all_basins_mask += the_mask rs_gcm_c = get_return_levels_and_unc_using_bootstrap(gcm_driven_config_c, varname=varname) rs_gcm_f = get_return_levels_and_unc_using_bootstrap(gcm_driven_config_f, varname=varname) plot_utils.apply_plot_params(font_size=10, width_cm=20, height_cm=18) # Plot return level changes fig = plt.figure() nplots = 0 for the_type, rp_to_rl in rs_gcm_c.return_lev_dict.items(): nplots += len(rp_to_rl) ncols = 2 nrows = nplots // ncols + int(nplots % ncols != 0) gs = GridSpec(nrows, ncols + 1, width_ratios=[1.0, ] * ncols + [0.05, ]) xx, yy = bmp_info.get_proj_xy() cmap = cm.get_cmap("bwr", 20) limits = { "high": (-50, 50), "low": (-150, 150) } for row, (the_type, rp_to_rl) in enumerate(sorted(rs_gcm_c.return_lev_dict.items(), key=lambda itm: itm[0])): for col, rp in enumerate(sorted(rp_to_rl)): ax = fig.add_subplot(gs[row, col]) rl = rp_to_rl[rp] # Ignore 0 return levels in the current climate for percentage calculations # rl = np.ma.masked_where(rl <= 0, rl) rl_future = rs_gcm_f.return_lev_dict[the_type][rp] # Calculate climate change signal diff = (rl_future - rl) / (np.abs(rl + rl_future) * 0.5) * 100 diff[(rl_future <= 0) & (rl <= 0)] = 0 # diff = rl diff = maskoceans(bmp_info.lons, bmp_info.lats, diff) print(diff.min(), diff.max()) std_c = rs_gcm_c.std_dict[the_type][rp] std_f = rs_gcm_f.std_dict[the_type][rp] significance = (np.ma.abs(diff) >= 1.96 * (std_c + std_f)) & (~diff.mask) significance = significance.astype(int) vmin, vmax = limits[the_type] diff = np.ma.masked_where(all_basins_mask < 0.5, diff) im = bmp_info.basemap.pcolormesh(xx, yy, diff, vmin=vmin, vmax=vmax, cmap=cmap) significance = np.ma.masked_where(all_basins_mask < 0.5, significance) cs = bmp_info.basemap.contourf(xx, yy, significance, levels=[0, 0.5, 1], hatches=["////", None, None], colors="none") if row == nrows - 1 and col == ncols - 1: # create a legend for the contour set artists, labels = cs.legend_elements() ax.legend([artists[0], ], ["not significant", ], handleheight=0.5, bbox_to_anchor=(1, -0.1), loc="upper right", borderaxespad=0.) ax.set_title("T = {}-year".format(rp)) if col == 0: ax.set_ylabel("{} flow".format(the_type)) bmp_info.basemap.drawcoastlines(ax=ax) bmp_info.basemap.drawmapboundary(fill_color="0.75") bmp_info.basemap.readshapefile(".".join(quebec_info.BASIN_BOUNDARIES_DERIVED_10km.split(".")[:-1]).replace("utm18", "latlon"), "basin", linewidth=1.2, ax=ax) if col == ncols - 1: cax = fig.add_subplot(gs[row, -1]) plt.colorbar(im, cax=cax, extend="both") cax.set_title("%") # Print basin average changes print("--- start ----------------{rp}-year {ext_type} flow ----------------".format(rp=rp, ext_type=the_type)) bname_to_diff = [(bname, diff[the_mask > 0.5].mean()) for bname, the_mask in bname_to_mask.items()] bname_to_diff = list(sorted(bname_to_diff, key=lambda item: item[1])) for bname, the_diff in bname_to_diff: print("{bname}: cc = {cc:.2f}%".format(bname=bname, cc=the_diff)) print("--- end ----------------{rp}-year {ext_type} flow ----------------".format(rp=rp, ext_type=the_type)) img_file = img_folder.joinpath("rl_cc_{}.png".format(gcm_driven_config_c.label)) with img_file.open("wb") as f: fig.savefig(f, bbox_inches="tight") plt.close(fig)
def main(): # get the data for basemap crcm_data_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5" bmp_info = analysis.get_basemap_info_from_hdf(file_path=crcm_data_path) season_key = "JJA" season_to_months = OrderedDict([(season_key, [6, 7, 8])]) month_to_ndays = {m: _month_to_ndays(m) for m in range(1, 13)} # current_filepath = ( "/RESCUE/skynet3_rech1/huziy/GCM_outputs/CanESM2/pr_Amon_CanESM2_historical_r1i1p1_185001-200512.nc" ) future_filepath = "/RESCUE/skynet3_rech1/huziy/GCM_outputs/CanESM2/pr_Amon_CanESM2_rcp85_r1i1p1_200601-210012.nc" Period = namedtuple("Period", ["start_year", "end_year"]) current = Period(start_year=1980, end_year=2010) future = Period(start_year=2070, end_year=2100) ds = xr.open_mfdataset([current_filepath, future_filepath]) # select the season ds = ds.isel(time=ds["time.season"] == season_key) # select the data for the current and future periods years = ds["time.year"] pr_current = ds.isel(time=(years >= current.start_year) & (years <= current.end_year)).pr pr_future = ds.isel(time=(years >= future.start_year) & (years <= future.end_year)).pr assert isinstance(pr_current, xr.DataArray) weights_current = xr.DataArray( [month_to_ndays[m] for m in pr_current["time.month"].values], coords=[pr_current.time] ) weights_current = weights_current / weights_current.sum() weights_future = xr.DataArray([month_to_ndays[m] for m in pr_future["time.month"].values], coords=[pr_future.time]) weights_future = weights_future / weights_future.sum() # seasonal means pr_current_smean = (pr_current * weights_current).groupby("time.year").sum(dim="time") pr_future_smean = (pr_future * weights_future).groupby("time.year").sum(dim="time") # climatology and stds pr_current_clim = pr_current_smean.mean(dim="year") pr_current_std = pr_current_smean.std(dim="year") pr_future_clim = pr_future_smean.mean(dim="year") pr_future_std = pr_future_smean.std(dim="year") # calculate significance n_current = current.end_year - current.start_year + 1 n_future = future.end_year - future.start_year + 1 tval, pval = stats.ttest_ind_from_stats( pr_current_clim.values, pr_current_std.values, nobs1=n_current, mean2=pr_future_clim.values, std2=pr_future_std.values, nobs2=n_future, ) print(weights_current[:3].values, weights_current[:3].sum()) print(pr_current_smean.shape) print(pr_future.shape) print(pr_current.shape) print(ds["time.year"][-12:]) # do the plotting plot_utils.apply_plot_params() fig = plt.figure() b = bmp_info.basemap xx, yy = bmp_info.get_proj_xy() lons, lats = np.meshgrid(ds.lon, ds.lat) xg, yg = b(lons, lats) dom_mask = (xg >= xx[0, 0]) & (xg <= xx[-1, -1]) & (yg >= yy[0, 0]) & (yg <= yy[-1, -1]) i_list, j_list = np.where(dom_mask) imax, jmax = i_list.max(), j_list.max() imin, jmin = i_list.min(), j_list.min() marginx, marginy = 10, 10 imax += marginx jmax += marginy imin -= marginx jmin -= marginy dom_mask[imin:imax, jmin:jmax] = True print(pr_current_clim.shape) print(ds.lon.shape) cchange = (pr_future_clim - pr_current_clim) * 24 * 3600 # Convert to mm/day cchange = np.ma.masked_where(~dom_mask, cchange) # cchange = np.ma.masked_where(pval > 0.1, cchange) plt.title("{}, (mm/day)".format(season_key)) im = b.contourf(xg, yg, cchange) cb = b.colorbar(im) sign = np.ma.masked_where(~dom_mask, pval <= 0.05) cs = b.contourf(xg, yg, sign, levels=[0, 0.5, 1], hatches=["/", None, None], colors="none") b.drawcoastlines() # create a legend for the contour set artists, labels = cs.legend_elements() plt.legend([artists[0]], ["not sign. (pvalue > 0.05)"], handleheight=2) img_folder = "cc-paper-comments" fig.savefig( os.path.join(img_folder, "canesm_cc_{}_precip.png".format(season_key)), dpi=common_plot_params.FIG_SAVE_DPI / 2, bbox_inches="tight", ) plt.show()
def main(): season_to_months = OrderedDict([(s, months) for s, months in DEFAULT_SEASON_TO_MONTHS.items() if s.lower() not in ["summer", "fall"]]) r_config_01 = RunConfig( data_path="/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5", start_year=1980, end_year=1996, label="CRCM5-L" ) r_config_04 = RunConfig( data_path="/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.4_crcm5-hcd-rl.hdf5", start_year=1980, end_year=1996, label="CRCM5-L(0.4)" ) r_config = r_config_04 # Number of points for aggregation nx_agg_model = 1 ny_agg_model = 1 nx_agg_obs = 2 ny_agg_obs = 2 r_config_cc = RunConfig( data_path="/RESCUE/skynet3_rech1/huziy/hdf_store/cc-canesm2-driven/quebec_0.1_crcm5-hcd-rl-cc-canesm2-1980-2010.hdf5", start_year=1980, end_year=1996, label="CRCM5-L" ) bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) if nx_agg_model * ny_agg_model > 1: bmp_info_agg = bmp_info.get_aggregated(nagg_x=nx_agg_model, nagg_y=ny_agg_model) else: bmp_info_agg = bmp_info # Validate temperature and precip model_vars = ["I5", ] obs_vars = ["SWE", ] obs_paths = [ "/RESCUE/skynet3_rech1/huziy/swe_ross_brown/swe.nc4", ] plot_all_vars_in_one_fig = True fig = None gs = None row_axes = None obs_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=12, height_cm=18) fig = plt.figure() ncols = len(season_to_months) + 1 gs = GridSpec(len(model_vars) * 3, 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, oname, opath in zip(model_vars, obs_vars, obs_paths): if plot_all_vars_in_one_fig: # Obs row is for observed values obs_row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols)] obs_row_axes[-1].set_title("mm") row += 1 model_row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols - 1)] row += 1 row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols)] row += 1 compare_vars(vname_model=mname, vname_obs=oname, r_config=r_config, season_to_months=season_to_months, nx_agg_model=nx_agg_model, ny_agg_model=ny_agg_model, nx_agg_obs=nx_agg_obs, ny_agg_obs=ny_agg_obs, bmp_info_agg=bmp_info_agg, bmp_info_model=bmp_info, obs_path=opath, diff_axes_list=row_axes, obs_axes_list=obs_row_axes, model_axes_list=model_row_axes) if plot_all_vars_in_one_fig: obs_row_axes[0].set_ylabel("(a)", rotation="horizontal", labelpad=10) model_row_axes[0].set_ylabel("(b)", rotation="horizontal", labelpad=10) row_axes[0].set_ylabel("(c)", rotation="horizontal", labelpad=10) for ax in row_axes[:-1]: ax.set_title("") # row_axes[0].annotate("(a)", (-0.2, 0.5), font_properties=FontProperties(weight="bold"), xycoords="axes fraction") # Plot bfe errs # row_axes = [fig.add_subplot(gs[row, col]) for col in range(ncols)] # plot_swe_bfes(r_config, r_config_cc, vname_model="I5", season_to_months=season_to_months, # bmp_info=bmp_info, axes_list=row_axes) # # row_axes[-1].set_visible(False) # row_axes[0].annotate("(b)", (0, 1.05), font_properties=FontProperties(weight="bold"), xycoords="axes fraction") # row_axes[0].set_ylabel("(b)", rotation="horizontal", labelpad=10) # for ax in row_axes[:-1]: # ax.set_title("") # Save the figure if necessary if plot_all_vars_in_one_fig: from crcm5.analyse_hdf import common_plot_params fig_path = img_folder.joinpath("{}_{}.png".format("_".join(model_vars), r_config.label)) with fig_path.open("wb") as figfile: fig.savefig(figfile, format="png", bbox_inches="tight", dpi=common_plot_params.FIG_SAVE_DPI) plt.close(fig)
def main(): vname = "VV" start_year = 1980 end_year = 2010 crcm_data_path = "/RESCUE/skynet3_rech1/huziy/hdf_store/quebec_0.1_crcm5-hcd-rl.hdf5" months_of_interest = [6, 7, 8] # summer summer_crcm = analysis.get_seasonal_climatology(hdf_path=crcm_data_path, start_year=start_year, end_year=end_year, level=0, var_name=vname, months=months_of_interest) bmp_info = analysis.get_basemap_info_from_hdf(file_path=crcm_data_path) erainterim_15_folder = "/RECH/data/Driving_data/Pilots/ERA-Interim_1.5/Pilots/" flist_for_season = get_files_for_season(erainterim_15_folder, start_year=start_year, end_year=end_year, months=months_of_interest) rpf = MultiRPN(flist_for_season) date_to_hu_erai15 = rpf.get_all_time_records_for_name_and_level(varname=vname, level=1000, level_kind=level_kinds.PRESSURE) summer_era15 = np.mean([field for field in date_to_hu_erai15.values()], axis=0) lons_era, lats_era = rpf.get_longitudes_and_latitudes_of_the_last_read_rec() # plotting # ERA-Interim plt.figure() b = Basemap(lon_0=180) xxg, yyg = b(lons_era, lats_era) im = b.contourf(xxg, yyg, summer_era15, 40, zorder=1) lonsr = bmp_info.lons.copy() lonsr[lonsr < 180] += 360 xxr, yyr = b(lonsr, bmp_info.lats) b.contourf(xxr, yyr, summer_crcm, levels=im.levels, norm=im.norm, cmap=im.cmap, zorder=2) b.drawcoastlines(zorder=3) plt.colorbar(im) # CRCM (plot both crcm and era on the same plot) fig = plt.figure() xx, yy = bmp_info.get_proj_xy() margin = 20 bext = bmp_info.basemap_for_extended_region(marginx=10 * margin, marginy=10 * margin) bmiddle = bmp_info.basemap_for_extended_region(marginx=9 * margin, marginy=9 * margin) xxg, yyg = bext(lons_era, lats_era) outer_domain = (xxg <= bext.urcrnrx) & (xxg >= bext.llcrnrx) & (yyg <= bext.urcrnry) & (yyg >= bext.llcrnry) summer_era15 = np.ma.masked_where(~outer_domain, summer_era15) im = bext.contourf(xx, yy, summer_crcm, levels=im.levels, norm=im.norm, cmap=im.cmap, zorder=2) bmiddle.contourf(xxg, yyg, summer_era15, levels=im.levels, norm=im.norm, cmap=im.cmap, zorder=1) bext.drawcoastlines() plt.colorbar(im) # Add a polygon ax = plt.gca() coords = np.array([ [xx[0, 0], yy[0, 0]], [xx[0, -1], yy[0, -1]], [xx[-1, -1], yy[-1, -1]], [xx[-1, 0], yy[-1, 0]] ]) ax.add_patch(Polygon(coords, facecolor="none", lw=3, zorder=3, edgecolor="k")) img_folder = "cc-paper-comments" if not os.path.isdir(img_folder): os.mkdir(img_folder) fig.savefig(os.path.join(img_folder, "{}_era_1.5_and_crcm.png".format(vname)), bbox_inches="tight", transparent=True) plt.show()
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-r.hdf5", start_year=1990, end_year=2010, label="CRCM5-L" ) bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) bmp_info.should_draw_grey_map_background = True bmp_info.should_draw_basin_boundaries = False bmp_info.map_bg_color = "0.75" station_ids = [ "104001", "093806", "093801", "081002", "081007", "080718" ] # get river network information used in the model flow_directions = analysis.get_array_from_file(r_config.data_path, var_name=infovar.HDF_FLOW_DIRECTIONS_NAME) accumulation_area_km2 = analysis.get_array_from_file(path=r_config.data_path, var_name=infovar.HDF_ACCUMULATION_AREA_NAME) cell_manager = CellManager(flow_dirs=flow_directions, lons2d=bmp_info.lons, lats2d=bmp_info.lats, accumulation_area_km2=accumulation_area_km2) # Get the list of stations to indicate on the bias map stations = cehq_station.read_station_data( start_date=None, end_date=None, selected_ids=station_ids ) """:type : list[Station]""" xx, yy = bmp_info.get_proj_xy() station_to_modelpoint = cell_manager.get_model_points_for_stations(station_list=stations) upstream_edges = cell_manager.get_upstream_polygons_for_points( model_point_list=station_to_modelpoint.values(), xx=xx, yy=yy) # Validate temperature, precip and swe obs_path_anusplin = "/home/huziy/skynet3_rech1/anusplin_links" obs_path_swe = "data/swe_ross_brown/swe.nc" model_var_to_obs_path = OrderedDict([ ("TT", obs_path_anusplin), # ("PR", obs_path_anusplin), ("I5", obs_path_swe) ]) vname_to_obs_data = {} # parameters that won't change in the loop over variable names params_const = dict(rconfig=r_config, bmp_info=bmp_info, season_to_months=season_to_months) for vname, obs_path in model_var_to_obs_path.items(): season_to_obs_data = get_seasonal_clim_obs_data(vname=vname, obs_path=obs_path, **params_const) # Comment swe over lakes, since I5 calculated only for land if vname in ["I5", ]: for season in season_to_obs_data: season_to_obs_data[season] = maskoceans(bmp_info.lons, bmp_info.lats, season_to_obs_data[season], inlands=True) vname_to_obs_data[vname] = season_to_obs_data # Plotting plot_all_vars_in_one_fig = True fig = None gs = None row_axes = [] 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=20) fig = plt.figure() ncols = len(season_to_months) + 1 gs = GridSpec(len(model_var_to_obs_path), 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 station_x_list = [] station_y_list = [] for mname in model_var_to_obs_path: 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) # -1 in order to exclude colorbars for the_ax in row_axes[:-1]: # Need titles only for the first row if row > 0: the_ax.set_title("") draw_upstream_area_bounds(the_ax, upstream_edges) if len(station_x_list) == 0: for the_station in stations: xst, yst = bmp_info.basemap(the_station.longitude, the_station.latitude) station_x_list.append(xst) station_y_list.append(yst) bmp_info.basemap.scatter(station_x_list, station_y_list, c="g", ax=the_ax, s=5, zorder=10, alpha=0.5) # Hide fall swe if mname in ["I5"]: row_axes[-2].set_visible(False) row += 1 # Save the figure if necessary if plot_all_vars_in_one_fig: fig_path = img_folder.joinpath("{}.png".format("_".join(model_var_to_obs_path))) 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 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 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=2009, label="CRCM5-L") # Number of points for aggregation nx_agg = 5 ny_agg = 5 bmp_info = analysis.get_basemap_info_from_hdf(file_path=r_config.data_path) bmp_info_agg = bmp_info.get_aggregated(nagg_x=nx_agg, nagg_y=ny_agg) # Validate temperature and precip model_vars = ["TT", "PR"] obs_vars = ["tmp", "pre"] obs_paths = [ "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.tmp.dat.nc", "/HOME/data/Validation/CRU_TS_3.1/Original_files_gzipped/cru_ts_3_10.1901.2009.pre.dat.nc" ] 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, oname, opath in zip(model_vars, obs_vars, obs_paths): 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_obs=oname, r_config=r_config, season_to_months=season_to_months, nx_agg_model=nx_agg, ny_agg_model=ny_agg, bmp_info_agg=bmp_info_agg, obs_path=opath, diff_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)