def entry_for_cc_canesm2_gl(): """ for CanESM2 driven CRCM5_NEMO simulation """ data_root = common_params.data_root label_to_datapath = OrderedDict([ (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_1989-2010_1989-2010/merged/" ), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_2079-2100_2079-2100/merged/" ), ]) cur_st_date = datetime(1989, 1, 1) cur_en_date = datetime(2011, 1, 1) # end date not inclusive fut_st_date = datetime(2079, 1, 1) fut_en_date = datetime(2101, 1, 1) # end date not inclusive cur_period = Period(cur_st_date, cur_en_date) fut_period = Period(fut_st_date, fut_en_date) periods_info = CcPeriodsInfo(cur_period=cur_period, fut_period=fut_period) season_to_months = OrderedDict([("ND", [11, 12]), ("JF", [1, 2]), ("MA", [3, 4])]) var_pairs = [("hles_snow", "TT"), ("hles_snow", "PR"), ("hles_snow", "lake_ice_fraction")] var_display_names = { "hles_snow": "HLES", "lake_ice_fraction": "Mean Lake ice \nfraction", "TT": "2m air\n temperature", "PR": "total\nprecipitation" } plot_utils.apply_plot_params(width_cm=25, height_cm=25, font_size=8) gl_mask = get_gl_mask(label_to_datapath[common_params.crcm_nemo_cur_label]) hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) main(label_to_data_path=label_to_datapath, var_pairs=var_pairs, periods_info=periods_info, vname_display_names=var_display_names, season_to_months=season_to_months, hles_region_mask=hles_region_mask, lakes_mask=gl_mask)
def entry_for_cc_canesm2_gl(): """ for CanESM2 driven CRCM5_NEMO simulation """ data_root = common_params.data_root label_to_datapath = OrderedDict([ (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_1989-2010_1989-2010/merged/"), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_2079-2100_2079-2100/merged/"), ]) cur_st_date = datetime(1989, 1, 1) cur_en_date = datetime(2011, 1, 1) # end date not inclusive fut_st_date = datetime(2079, 1, 1) fut_en_date = datetime(2101, 1, 1) # end date not inclusive cur_period = Period(cur_st_date, cur_en_date) fut_period = Period(fut_st_date, fut_en_date) periods_info = CcPeriodsInfo(cur_period=cur_period, fut_period=fut_period) season_to_months = OrderedDict([ ("ND", [11, 12]), ("JF", [1, 2]), ("MA", [3, 4]) ]) var_pairs = [("hles_snow", "TT"), ("hles_snow", "PR"), ("hles_snow", "lake_ice_fraction")] var_display_names = { "hles_snow": "HLES", "lake_ice_fraction": "Mean Lake ice \nfraction", "TT": "2m air\n temperature", "PR": "total\nprecipitation" } plot_utils.apply_plot_params(width_cm=25, height_cm=25, font_size=8) gl_mask = get_gl_mask(label_to_datapath[common_params.crcm_nemo_cur_label]) hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) main(label_to_data_path=label_to_datapath, var_pairs=var_pairs, periods_info=periods_info, vname_display_names=var_display_names, season_to_months=season_to_months, hles_region_mask=hles_region_mask, lakes_mask=gl_mask)
def main(varname=""): plot_utils.apply_plot_params(width_cm=22, height_cm=5, font_size=8) # series = get_monthly_accumulations_area_avg(data_dir="/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_NEMO_1980-2009_monthly", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_HL_1980-2009_monthly", # varname=varname) selected_months = [9, 10, 11, 12, 1, 2, 3, 4, 5] data_root = common_params.data_root label_to_datapath = OrderedDict([ # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009"), # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_daily_Obs_monthly_icefix_1980-2009"), (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_1989-2010_1989-2010"), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_2079-2100_2079-2100"), ]) label_to_series = OrderedDict() label_to_color = { common_params.crcm_nemo_cur_label: "skyblue", common_params.crcm_nemo_fut_label: "salmon" } gl_mask = get_gl_mask(label_to_datapath[common_params.crcm_nemo_cur_label] / "merged") hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) # select a file from the directory sel_file = None for f in label_to_datapath[common_params.crcm_nemo_cur_label].iterdir(): sel_file = f with xarray.open_dataset(sel_file) as ds: hles_region_mask_lons, hles_region_mask_lats = [ds[k].values for k in ["lon", "lat"]] for label, datapath in label_to_datapath.items(): series = get_monthly_accumulations_area_avg(data_dir=datapath, varname=varname, fname_suffix="_daily.nc", region_of_interest_mask=hles_region_mask) label_to_series[label] = series # # print(series) # assert isinstance(series, pd.Series) # ax = series.plot(kind="bar", width=1) # # ax.set_ylabel("%") # ax.set_xlabel("Month") gs = GridSpec(1, 2, wspace=0.) fig = plt.figure() ax = fig.add_subplot(gs[0, 1]) start_date = datetime(2001, 10, 1) dates = [start_date.replace(month=(start_date.month + i) % 13 + int((start_date.month + i) % 13 == 0), year=start_date.year + (start_date.month + i) // 13) for i in range(13)] def format_month_label(x, pos): print(num2date(x)) return "{:%b}".format(num2date(x)) # calculate bar widths dates_num = date2num(dates) width = np.diff(dates_num) / (len(label_to_series) * 1.5) width = np.array([width[0] for _ in width]) # select the months width = np.array([w for w, d in zip(width, dates) if d.month in selected_months]) dates = [d for d in dates[:-1] if d.month in selected_months] dates_num = date2num(dates) label_to_handle = OrderedDict() label_to_annual_hles = OrderedDict() for i, (label, series) in enumerate(label_to_series.items()): values = [series[d.month] for d in dates] # convert to percentages values_sum = sum(values) # save the total annual hles for later reuse label_to_annual_hles[label] = values_sum values = [v / values_sum * 100 for v in values] print(label, values) print(f"sum(values) = {sum(values)}") h = ax.bar(dates_num + i * width, values, width=width, align="edge", linewidth=0.5, edgecolor="k", facecolor=label_to_color[label], label=label, zorder=10) label_to_handle[label] = h ax.set_ylabel("% of total HLES") ax.set_title("(b) Monthly HLES distribution") ax.xaxis.set_major_formatter(FuncFormatter(func=format_month_label)) ax.xaxis.set_major_locator(MonthLocator(bymonthday=int(sum(width[:len(label_to_series)]) / 2.) + 1)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # ax.set_title(common_params.varname_to_display_name[varname]) ax.yaxis.grid(True, linestyle="--", linewidth=0.5) # ax.text(1, 1, "(a)", fontdict=dict(weight="bold"), transform=ax.transAxes, va="top", ha="right") ax_with_legend = ax # area average annual total HLES text_align_props = dict(transform=ax.transAxes, va="bottom", ha="right") cur_hles_annual = label_to_annual_hles[common_params.crcm_nemo_cur_label] fut_hles_annual = label_to_annual_hles[common_params.crcm_nemo_fut_label] ax.text(1, 0.2, r"$\Delta_{\rm total}$" + f"({(fut_hles_annual - cur_hles_annual) / cur_hles_annual * 100:.1f}%)", **text_align_props, fontdict=dict(size=6)) # Plot the domain and the HLES region of interest ax = fig.add_subplot(gs[0, 0]) topo_nc_file = data_root / "geophys_452x260_me.nc" ax = plot_domain_and_interest_region(ax, topo_nc_file) ax.set_title("(a) Experimental domain") # Add a common legend labels = list(label_to_handle) handles = [label_to_handle[l] for l in labels] ax_with_legend.legend(handles, labels, bbox_to_anchor=(0, -0.18), loc="upper left", borderaxespad=0., ncol=2) # ax.grid() sel_months_str = "_".join([str(m) for m in selected_months]) common_params.img_folder.mkdir(exist_ok=True) img_file = common_params.img_folder / f"{varname}_histo_cc_m{sel_months_str}_domain.png" print(f"Saving plot to {img_file}") fig.savefig(img_file, **common_params.image_file_options)
def main(varname=""): plot_utils.apply_plot_params(width_cm=18, height_cm=5.5, font_size=8) # series = get_monthly_accumulations_area_avg(data_dir="/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_NEMO_1980-2009_monthly", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_HL_1980-2009_monthly", # varname=varname) selected_months = [9, 10, 11, 12, 1, 2, 3, 4, 5] data_root = common_params.data_root label_to_datapath = OrderedDict([ # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009"), # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_daily_Obs_monthly_icefix_1980-2009"), (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_HL_CanESM2_RCP85_1989-2010_1989-2010"), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_HL_CanESM2_RCP85_2079-2100_2079-2100"), ]) label_to_series = OrderedDict() label_to_color = { common_params.crcm_nemo_cur_label: "skyblue", common_params.crcm_nemo_fut_label: "salmon" } gl_mask = get_gl_mask( label_to_datapath[common_params.crcm_nemo_cur_label] / "merged") hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=10) for label, datapath in label_to_datapath.items(): series = get_monthly_accumulations_area_avg( data_dir=datapath, varname=varname, fname_suffix="_daily.nc", region_of_interest_mask=hles_region_mask) label_to_series[label] = series # # print(series) # assert isinstance(series, pd.Series) # ax = series.plot(kind="bar", width=1) # # ax.set_ylabel("%") # ax.set_xlabel("Month") gs = GridSpec(1, 2, wspace=0.4) fig = plt.figure() ax = fig.add_subplot(gs[0, 0]) start_date = datetime(2001, 10, 1) dates = [ start_date.replace(month=(start_date.month + i) % 13 + int((start_date.month + i) % 13 == 0), year=start_date.year + (start_date.month + i) // 13) for i in range(13) ] def format_month_label(x, pos): print(num2date(x)) return "{:%b}".format(num2date(x)) # calculate bar widths dates_num = date2num(dates) width = np.diff(dates_num) / (len(label_to_series) * 1.5) width = np.array([width[0] for _ in width]) # select the months width = np.array( [w for w, d in zip(width, dates) if d.month in selected_months]) dates = [d for d in dates[:-1] if d.month in selected_months] dates_num = date2num(dates) label_to_handle = OrderedDict() label_to_annual_hles = OrderedDict() for i, (label, series) in enumerate(label_to_series.items()): values = [series[d.month] for d in dates] # convert to percentages values_sum = sum(values) # save the total annual hles for later reuse label_to_annual_hles[label] = values_sum values = [v / values_sum * 100 for v in values] print(label, values) print(f"sum(values) = {sum(values)}") h = ax.bar(dates_num + i * width, values, width=width, align="edge", linewidth=0.5, edgecolor="k", facecolor=label_to_color[label], label=label, zorder=10) label_to_handle[label] = h ax.set_ylabel("% of total HLES") ax.xaxis.set_major_formatter(FuncFormatter(func=format_month_label)) ax.xaxis.set_major_locator( MonthLocator(bymonthday=int(sum(width[:len(label_to_series)]) / 2.) + 1)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # ax.set_title(common_params.varname_to_display_name[varname]) ax.yaxis.grid(True, linestyle="--", linewidth=0.5) ax.text(1, 1, "(a)", fontdict=dict(weight="bold"), transform=ax.transAxes, va="top", ha="right") ax_with_legend = ax # area average annual total HLES text_align_props = dict(transform=ax.transAxes, va="bottom", ha="right") cur_hles_annual = label_to_annual_hles[common_params.crcm_nemo_cur_label] fut_hles_annual = label_to_annual_hles[common_params.crcm_nemo_fut_label] ax.text( 1, 0.2, r"$\Delta_{\rm total}$" + f"({(fut_hles_annual - cur_hles_annual) / cur_hles_annual * 100:.1f}%)", **text_align_props, fontdict=dict(size=6)) print(width[:len(label_to_series)]) # plot HLES amount changes for each month ax = fig.add_subplot(gs[0, 1], sharex=ax) cur_data = label_to_series[common_params.crcm_nemo_cur_label] fut_data = label_to_series[common_params.crcm_nemo_fut_label] perc_change = (fut_data - cur_data) / cur_data * 100.0 perc_change_sel = [perc_change[d.month] for d in dates] h = ax.bar(dates_num + width, perc_change_sel, edgecolor="k", linewidth=0.5, facecolor="orange", width=10, align="center", zorder=10) label_to_handle[r"CRCM5_NEMO(f-c)"] = h ax.set_ylabel("% of current HLES") ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.yaxis.grid(True, linestyle="--", linewidth=0.5) ax.text(1, 1, "(b)", fontdict=dict(weight="bold"), transform=ax.transAxes, va="top", ha="right") # Add a common legend labels = list(label_to_handle) handles = [label_to_handle[l] for l in labels] ax_with_legend.legend(handles, labels, bbox_to_anchor=(0, -0.18), loc="upper left", borderaxespad=0., ncol=1) # ax.grid() sel_months_str = "_".join([str(m) for m in selected_months]) common_params.img_folder.mkdir(exist_ok=True) img_file = common_params.img_folder / f"{varname}_histo_cc_m{sel_months_str}_HL.png" print(f"Saving plot to {img_file}") fig.savefig(img_file, **common_params.image_file_options)
def main(varname=""): plot_utils.apply_plot_params(width_cm=22, height_cm=5, font_size=8) # series = get_monthly_accumulations_area_avg(data_dir="/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_NEMO_1980-2009_monthly", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_HL_1980-2009_monthly", # varname=varname) hles_bin_edges = np.arange(0.1, 0.34, 0.02) # selected_months = [10, 11, 12, 1, 2, 3, 4, 5] selected_seasons = OrderedDict([("ND", [11, 12]), ("JF", [1, 2]), ("MA", [3, 4]), ("NDJFMA", [11, 12, 1, 2, 3, 4])]) data_root = common_params.data_root label_to_datapath = OrderedDict([ # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009"), # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_daily_Obs_monthly_icefix_1980-2009"), # (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_1989-2010_1989-2010" / "merged"), # (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_2079-2100_2079-2100" / "merged"), (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_fix_CanESM2_RCP85_1989-2010_monthly_1989-2010" / "merged"), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_fix_CanESM2_RCP85_2079-2100_monthly_2079-2100" / "merged"), ]) # longutudes and latitudes of the focus region around the Great Lakes (we define it, mostly for performance # issues and to eliminate regions with 0 hles that still are in the 200 km HLES zone) focus_region_lonlat_nc_file = data_root / "lon_lat.nc" label_to_series = OrderedDict() label_to_color = { common_params.crcm_nemo_cur_label: "skyblue", common_params.crcm_nemo_fut_label: "salmon" } gl_mask = get_gl_mask(label_to_datapath[common_params.crcm_nemo_cur_label]) hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) # select a file from the directory sel_file = None for f in label_to_datapath[common_params.crcm_nemo_cur_label].iterdir(): if f.is_file(): sel_file = f break assert sel_file is not None, f"Could not find any files in {label_to_datapath[common_params.crcm_nemo_cur_label]}" # Take into account the focus region with xarray.open_dataset(sel_file) as ds: hles_region_mask_lons, hles_region_mask_lats = [ ds[k].values for k in ["lon", "lat"] ] with xarray.open_dataset(focus_region_lonlat_nc_file) as ds_focus: focus_lons, focus_lats = [ ds_focus[k].values for k in ["lon", "lat"] ] coords_src = lat_lon.lon_lat_to_cartesian( hles_region_mask_lons.flatten(), hles_region_mask_lats.flatten()) coords_dst = lat_lon.lon_lat_to_cartesian(focus_lons.flatten(), focus_lats.flatten()) ktree = KDTree(list(zip(*coords_src))) dists, inds = ktree.query(list(zip(*coords_dst)), k=1) focus_mask = hles_region_mask.flatten() focus_mask[...] = False focus_mask[inds] = True focus_mask.shape = hles_region_mask.shape for seas_name, selected_months in selected_seasons.items(): # read and calculate for label, datapath in label_to_datapath.items(): hles_file = None # select hles file in the folder for f in datapath.iterdir(): if f.name.endswith("_daily.nc"): hles_file = f break assert hles_file is not None, f"Could not find any HLES files in {datapath}" series = get_hles_amount_distribution_from_merged( data_file=hles_file, varname=varname, region_of_interest_mask=hles_region_mask & focus_mask, selected_months=selected_months, bin_edges=hles_bin_edges) label_to_series[label] = series # plotting gs = GridSpec(1, 1, wspace=0.05) fig = plt.figure() ax = fig.add_subplot(gs[0, 0]) # calculate bar widths widths = np.diff(hles_bin_edges) label_to_handle = OrderedDict() for i, (label, series) in enumerate(label_to_series.items()): values = series.values if hasattr(series, "values") else series # values = values / values.sum() * 100 logger.debug([label, values]) logger.debug(f"sum(values) = {sum(values)}") # h = ax.bar(hles_bin_edges[:-1] + i * widths / len(label_to_series), values, width=widths / len(label_to_series), # align="edge", linewidth=0.5, # edgecolor="k", # facecolor=label_to_color[label], label=label, zorder=10) h = ax.plot(hles_bin_edges[:-1], values, color=label_to_color[label], marker="o", label=label, markersize=2.5) # label_to_handle[label] = h ax.set_xlabel("HLES (m)") ax.set_title(f"HLES distribution, {seas_name}") ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # ax.set_title(common_params.varname_to_display_name[varname]) ax.yaxis.grid(True, linestyle="--", linewidth=0.5) # ax.text(1, 1, "(a)", fontdict=dict(weight="bold"), transform=ax.transAxes, va="top", ha="right") ax_with_legend = ax ax.set_xlim((0.1, None)) # area average annual total HLES text_align_props = dict(transform=ax.transAxes, va="bottom", ha="right") # Plot the domain and the HLES region of interest # ax = fig.add_subplot(gs[0, 0]) # topo_nc_file = data_root / "geophys_452x260_me.nc" # ax = plot_domain_and_interest_region(ax, topo_nc_file, focus_region_lonlat_nc_file=focus_region_lonlat_nc_file) # ax.set_title("(a) Experimental domain") # # # Add a common legend labels = list(label_to_handle) handles = [label_to_handle[l] for l in labels] ax_with_legend.legend(bbox_to_anchor=(0, -0.18), loc="upper left", borderaxespad=0., ncol=2) # ax.grid() sel_months_str = "_".join([str(m) for m in selected_months]) common_params.img_folder.mkdir(exist_ok=True) img_file = common_params.img_folder / f"{varname}_histo_amount_cc_m{sel_months_str}_domain.png" print(f"Saving plot to {img_file}") fig.savefig(img_file, **common_params.image_file_options)
def plot_domain_and_interest_region(ax: Axes, topo_nc_file_path: Path, focus_region_lonlat_nc_file: Path = None): """ :param focus_region_lonlat_nc_file: Path to the file containing focus region lons and lats :param region_mask_lats: latitudes corresponding to the region mask :param region_mask_lons: :param ax: :param topo_nc_file_path: :param region_mask: Note: below is the expected structure of the input netcdf file $ ncdump -h geophys_452x260_me.nc netcdf geophys_452x260_me { dimensions: x = 452 ; y = 260 ; variables: float ME(x, y) ; float lon(x, y) ; float lat(x, y) ; int proj_params ; proj_params:grid_type = "E" ; proj_params:lat1 = 0. ; proj_params:lon1 = 180. ; proj_params:lat2 = 1. ; proj_params:lon2 = 276. ; } """ # read the model topography from the file with xarray.open_dataset(topo_nc_file_path) as topo_ds: topo_lons, topo_lats, topo = [ topo_ds[k].values for k in ["lon", "lat", "ME"] ] prj_params = topo_ds["proj_params"] rll = RotatedLatLon(lon1=prj_params.lon1, lat1=prj_params.lat1, lon2=prj_params.lon2, lat2=prj_params.lat2) rot_pole_cpy = rll.get_cartopy_projection_obj() ax.set_visible(False) ax = ax.figure.add_axes(ax.get_position().bounds, projection=rot_pole_cpy) # ax.coastlines() gl_mask = get_gl_mask(topo_nc_file_path) region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) topo_lons[topo_lons > 180] -= 360 xll, yll = rot_pole_cpy.transform_point(topo_lons[0, 0], topo_lats[0, 0], cartopy.crs.PlateCarree()) xur, yur = rot_pole_cpy.transform_point(topo_lons[-1, -1], topo_lats[-1, -1], cartopy.crs.PlateCarree()) map_extent = [xll, xur, yll, yur] print("Map extent: ", map_extent) topo_clevs = [0, 100, 200, 300, 400, 500, 600, 800, 1000, 1200] # bn = BoundaryNorm(topo_clevs, len(topo_clevs) - 1) cmap = cm.get_cmap("terrain") ocean_color = cmap(0.18) cmap, norm = colors.from_levels_and_colors( topo_clevs, cmap(np.linspace(0.3, 1, len(topo_clevs) - 1))) xyz_coords = rot_pole_cpy.transform_points(cartopy.crs.PlateCarree(), topo_lons, topo_lats) xx = xyz_coords[:, :, 0] yy = xyz_coords[:, :, 1] add_rectangle(ax, xx, yy, margin=20, edge_style="solid", zorder=10, linewidth=0.5) add_rectangle(ax, xx, yy, margin=10, edge_style="dashed", zorder=10, linewidth=0.5) # plot a rectangle for the focus region if focus_region_lonlat_nc_file is not None: with xarray.open_dataset(focus_region_lonlat_nc_file) as fr: focus_lons, focus_lats = fr["lon"].data, fr["lat"].data xyz_coords = rot_pole_cpy.transform_points( cartopy.crs.PlateCarree(), focus_lons, focus_lats) xxf, yyf = xyz_coords[..., 0], xyz_coords[..., 1] add_rectangle(ax, xxf, yyf, edge_style="solid", margin=0, edgecolor="magenta", zorder=10, linewidth=1) cs = ax.pcolormesh(topo_lons[:, :], topo_lats[:, :], topo[:, :], transform=cartopy.crs.PlateCarree(), cmap=cmap, norm=norm) to_plot = np.ma.masked_where(region_mask < 0.5, region_mask) ax.scatter(topo_lons, topo_lats, to_plot * 0.01, c="cyan", transform=cartopy.crs.PlateCarree(), alpha=0.5) # Add geographic features line_color = "k" ax.add_feature(common_params.LAKES_50m, facecolor=cartopy.feature.COLORS["water"], edgecolor=line_color, linewidth=0.5) ax.add_feature(common_params.OCEAN_50m, facecolor=cartopy.feature.COLORS["water"], edgecolor=line_color, linewidth=0.5) ax.add_feature(common_params.COASTLINE_50m, facecolor="none", edgecolor=line_color, linewidth=0.5) ax.add_feature(common_params.RIVERS_50m, facecolor="none", edgecolor=line_color, linewidth=0.5) ax.set_extent(map_extent, crs=rot_pole_cpy) # improve colorbar divider = make_axes_locatable(ax) ax_cb = divider.new_vertical(size="5%", pad=0.1, axes_class=plt.Axes, pack_start=True) ax.figure.add_axes(ax_cb) cb = plt.colorbar(cs, cax=ax_cb, orientation="horizontal") cb.ax.set_xticklabels(topo_clevs, rotation=45) return ax
def main(varname=""): plot_utils.apply_plot_params(width_cm=22, height_cm=5, font_size=8) # series = get_monthly_accumulations_area_avg(data_dir="/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_NEMO_1980-2009_monthly", # varname=varname) # series = get_monthly_accumulations_area_avg(data_dir="/RESCUE/skynet3_rech1/huziy/Netbeans Projects/Python/RPN/lake_effect_analysis_CRCM5_HL_1980-2009_monthly", # varname=varname) selected_months = [10, 11, 12, 1, 2, 3, 4, 5] data_root = common_params.data_root label_to_datapath = OrderedDict([ # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_Obs_monthly_1980-2009"), # ("Obs", "/HOME/huziy/skynet3_rech1/Netbeans Projects/Python/RPN/lake_effect_analysis_daily_Obs_monthly_icefix_1980-2009"), # (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_1989-2010_1989-2010" / "merged"), # (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_CanESM2_RCP85_2079-2100_2079-2100" / "merged"), (common_params.crcm_nemo_cur_label, data_root / "lake_effect_analysis_CRCM5_NEMO_fix_CanESM2_RCP85_1989-2010_monthly_1989-2010" / "merged"), (common_params.crcm_nemo_fut_label, data_root / "lake_effect_analysis_CRCM5_NEMO_fix_CanESM2_RCP85_2079-2100_monthly_2079-2100" / "merged"), ]) # longutudes and latitudes of the focus region around the Great Lakes (we define it, mostly for performance # issues and to eliminate regions with 0 hles that still are in the 200 km HLES zone) focus_region_lonlat_nc_file = data_root / "lon_lat.nc" label_to_series = OrderedDict() label_to_color = { common_params.crcm_nemo_cur_label: "skyblue", common_params.crcm_nemo_fut_label: "salmon" } gl_mask = get_gl_mask(label_to_datapath[common_params.crcm_nemo_cur_label]) hles_region_mask = get_mask_of_points_near_lakes(gl_mask, npoints_radius=20) # select a file from the directory sel_file = None for f in label_to_datapath[common_params.crcm_nemo_cur_label].iterdir(): if f.is_file(): sel_file = f break assert sel_file is not None, f"Could not find any files in {label_to_datapath[common_params.crcm_nemo_cur_label]}" # Take into account the focus region with xarray.open_dataset(sel_file) as ds: hles_region_mask_lons, hles_region_mask_lats = [ ds[k].values for k in ["lon", "lat"] ] with xarray.open_dataset(focus_region_lonlat_nc_file) as ds_focus: focus_lons, focus_lats = [ ds_focus[k].values for k in ["lon", "lat"] ] coords_src = lat_lon.lon_lat_to_cartesian( hles_region_mask_lons.flatten(), hles_region_mask_lats.flatten()) coords_dst = lat_lon.lon_lat_to_cartesian(focus_lons.flatten(), focus_lats.flatten()) ktree = KDTree(list(zip(*coords_src))) dists, inds = ktree.query(list(zip(*coords_dst)), k=1) focus_mask = hles_region_mask.flatten() focus_mask[...] = False focus_mask[inds] = True focus_mask.shape = hles_region_mask.shape for label, datapath in label_to_datapath.items(): hles_file = None for f in datapath.iterdir(): if f.name.endswith("_daily.nc"): hles_file = f break assert hles_file is not None, f"Could not find any HLES files in {datapath}" series = get_monthly_accumulations_area_avg_from_merged( data_file=hles_file, varname=varname, region_of_interest_mask=hles_region_mask & focus_mask) label_to_series[label] = series # plotting gs = GridSpec(1, 2, wspace=0.05) fig = plt.figure() ax = fig.add_subplot(gs[0, 1]) start_date = datetime(2001, 10, 1) dates = [ start_date.replace(month=(start_date.month + i) % 13 + int((start_date.month + i) % 13 == 0), year=start_date.year + (start_date.month + i) // 13) for i in range(13) ] def format_month_label(x, pos): logging.debug(num2date(x)) return "{:%b}".format(num2date(x)) # calculate bar widths dates_num = date2num(dates) width = np.diff(dates_num) / (len(label_to_series) * 1.5) width = np.array([width[0] for _ in width]) # select the months width = np.array( [w for w, d in zip(width, dates) if d.month in selected_months]) dates = [d for d in dates[:-1] if d.month in selected_months] dates_num = date2num(dates) label_to_handle = OrderedDict() label_to_annual_hles = OrderedDict() for i, (label, series) in enumerate(label_to_series.items()): values = [series[d.month] * 100 for d in dates] # convert to percentages values_sum = sum(values) # save the total annual hles for later reuse label_to_annual_hles[label] = values_sum # values = [v / values_sum * 100 for v in values] logger.debug([label, values]) logger.debug(f"sum(values) = {sum(values)}") h = ax.bar(dates_num + i * width, values, width=width, align="edge", linewidth=0.5, edgecolor="k", facecolor=label_to_color[label], label=label, zorder=10) label_to_handle[label] = h ax.set_ylabel("HLES (cm/day)") ax.set_title("(b) Monthly HLES distribution") ax.xaxis.set_major_formatter(FuncFormatter(func=format_month_label)) ax.xaxis.set_major_locator( MonthLocator(bymonthday=int(sum(width[:len(label_to_series)]) / 2.) + 1)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # ax.set_title(common_params.varname_to_display_name[varname]) ax.yaxis.grid(True, linestyle="--", linewidth=0.5) # ax.text(1, 1, "(a)", fontdict=dict(weight="bold"), transform=ax.transAxes, va="top", ha="right") ax_with_legend = ax # area average annual total HLES text_align_props = dict(transform=ax.transAxes, va="bottom", ha="right") cur_hles_annual = label_to_annual_hles[common_params.crcm_nemo_cur_label] fut_hles_annual = label_to_annual_hles[common_params.crcm_nemo_fut_label] ax.text( 1, 0.2, r"$\Delta_{\rm total}$" + f"({(fut_hles_annual - cur_hles_annual) / cur_hles_annual * 100:.1f}%)", **text_align_props, fontdict=dict(size=6)) # Plot the domain and the HLES region of interest ax = fig.add_subplot(gs[0, 0]) topo_nc_file = data_root / "geophys_452x260_me.nc" ax = plot_domain_and_interest_region( ax, topo_nc_file, focus_region_lonlat_nc_file=focus_region_lonlat_nc_file) ax.set_title("(a) Experimental domain") # Add a common legend labels = list(label_to_handle) handles = [label_to_handle[l] for l in labels] ax_with_legend.legend(handles, labels, bbox_to_anchor=(0, -0.18), loc="upper left", borderaxespad=0., ncol=2) # ax.grid() sel_months_str = "_".join([str(m) for m in selected_months]) common_params.img_folder.mkdir(exist_ok=True) img_file = common_params.img_folder / f"{varname}_histo_cc_m{sel_months_str}_domain.png" print(f"Saving plot to {img_file}") fig.savefig(img_file, **common_params.image_file_options)