def plot_errors_in_one_figure(season_to_diff, fig_path="", **kwargs): fig = plt.figure() basemap = kwargs["basemap"] x, y = kwargs["x"], kwargs["y"] vmin, vmax = None, None for k, field in season_to_diff.items(): pl, ph = field.min(), field.max() if vmin is None: vmin = pl vmax = ph else: vmin = min(vmin, pl) vmax = max(vmax, ph) print("min,max = ({0}, {1})".format(vmin, vmax)) ncolors = 25 if vmin * vmax <= 0: cmap = cm.get_cmap("RdBu_r", ncolors) else: if vmin >= 0: cmap = cm.get_cmap("Reds", ncolors) else: cmap = cm.get_cmap("Blues_r", ncolors) bn, bounds, vmin, vmax = infovar.get_boundary_norm(vmin, vmax, ncolors, exclude_zero=True, difference=True) gs = GridSpec(len(season_to_diff), 2, width_ratios=[1, 0.05]) row = 0 img = None for the_seasson, the_diff in season_to_diff.items(): ax = fig.add_subplot(gs[row, 0]) #img = basemap.pcolormesh(x, y, the_diff, ax = ax, norm = bn, cmap = cmap, vmin = vmin, vmax = vmax) img = basemap.contourf(x, y, the_diff, ax=ax, norm=bn, cmap=cmap, extend="both", levels=bounds) ax.set_title(the_seasson) basemap.drawcoastlines() row += 1 cax = fig.add_subplot(gs[:, 1]) plt.colorbar(img, ticks=bounds, orientation="vertical", cax=cax, extend="both") fig.savefig(fig_path, bbox_inches="tight")
def plot_errors_in_one_figure(season_to_diff, fig_path="", **kwargs): fig = plt.figure() basemap = kwargs["basemap"] x, y = kwargs["x"], kwargs["y"] vmin, vmax = None, None for k, field in season_to_diff.items(): pl, ph = field.min(), field.max() if vmin is None: vmin = pl vmax = ph else: vmin = min(vmin, pl) vmax = max(vmax, ph) print("min,max = ({0}, {1})".format(vmin, vmax)) ncolors = 25 if vmin * vmax <= 0: cmap = cm.get_cmap("RdBu_r", ncolors) else: if vmin >= 0: cmap = cm.get_cmap("Reds", ncolors) else: cmap = cm.get_cmap("Blues_r", ncolors) bn, bounds, vmin, vmax = infovar.get_boundary_norm(vmin, vmax, ncolors, exclude_zero=True, difference=True) gs = GridSpec(len(season_to_diff), 2, width_ratios=[1, 0.05]) row = 0 img = None for the_seasson, the_diff in season_to_diff.items(): ax = fig.add_subplot(gs[row, 0]) #img = basemap.pcolormesh(x, y, the_diff, ax = ax, norm = bn, cmap = cmap, vmin = vmin, vmax = vmax) img = basemap.contourf(x, y, the_diff, ax = ax, norm = bn, cmap = cmap, extend = "both", levels = bounds) ax.set_title(the_seasson) basemap.drawcoastlines() row += 1 cax = fig.add_subplot(gs[:, 1]) plt.colorbar(img,ticks = bounds, orientation = "vertical", cax = cax, extend = "both") fig.savefig(fig_path, bbox_inches = "tight")
def compare(paths=None, path_to_control_data=None, control_label="", labels=None, varnames=None, levels=None, months_of_interest=None, start_year=None, end_year=None): """ Comparing 2D fields :param paths: paths to the simulation results :param varnames: :param labels: Display name for each simulation (number of labels should be equal to the number of paths) :param path_to_control_data: the path with which the comparison done i.e. a in the following formula delta = (x - a)/a * 100% generates one image file per variable (in the folder images_for_lake-river_paper): compare_varname_<control_label>_<label1>_..._<labeln>_startyear_endyear.png """ # get coordinate data (assumes that all the variables and runs have the same coordinates) lons2d, lats2d, basemap = analysis.get_basemap_from_hdf(file_path=path_to_control_data) x, y = basemap(lons2d, lats2d) lake_fraction = analysis.get_array_from_file(path=path_to_control_data, var_name="lake_fraction") if lake_fraction is None: lake_fraction = np.zeros(lons2d.shape) ncolors = 10 # +1 to include white diff_cmap = cm.get_cmap("RdBu_r", ncolors + 1) for var_name, level in zip(varnames, levels): sfmt = infovar.get_colorbar_formatter(var_name) control_means = analysis.get_mean_2d_fields_for_months(path=path_to_control_data, var_name=var_name, months=months_of_interest, start_year=start_year, end_year=end_year, level=level) control_mean = np.mean(control_means, axis=0) fig = plt.figure() assert isinstance(fig, Figure) gs = gridspec.GridSpec(2, len(paths) + 1, wspace=0.5) # plot the control ax = fig.add_subplot(gs[0, 0]) assert isinstance(ax, Axes) ax.set_title("{0}".format(control_label)) ax.set_ylabel("Mean: $X_{0}$") to_plot = infovar.get_to_plot(var_name, control_mean, lake_fraction=lake_fraction, mask_oceans=True, lons=lons2d, lats=lats2d) # determine colorabr extent and spacing field_cmap, field_norm = infovar.get_colormap_and_norm_for(var_name, to_plot, ncolors=ncolors) basemap.pcolormesh(x, y, to_plot, cmap=field_cmap, norm=field_norm) cb = basemap.colorbar(format=sfmt) assert isinstance(cb, Colorbar) # cb.ax.set_ylabel(infovar.get_units(var_name)) units = infovar.get_units(var_name) info = "Variable:" \ "\n{0}" \ "\nPeriod: {1}-{2}" \ "\nMonths: {3}" \ "\nUnits: {4}" info = info.format(infovar.get_long_name(var_name), start_year, end_year, ",".join([datetime(2001, m, 1).strftime("%b") for m in months_of_interest]), units) ax.annotate(info, xy=(0.1, 0.3), xycoords="figure fraction") sel_axes = [ax] for the_path, the_label, column in zip(paths, labels, list(range(1, len(paths) + 1))): means_for_years = analysis.get_mean_2d_fields_for_months(path=the_path, var_name=var_name, months=months_of_interest, start_year=start_year, end_year=end_year) the_mean = np.mean(means_for_years, axis=0) # plot the mean value ax = fig.add_subplot(gs[0, column]) sel_axes.append(ax) ax.set_title("{0}".format(the_label)) to_plot = infovar.get_to_plot(var_name, the_mean, lake_fraction=lake_fraction, mask_oceans=True, lons=lons2d, lats=lats2d) basemap.pcolormesh(x, y, to_plot, cmap=field_cmap, norm=field_norm) ax.set_ylabel("Mean: $X_{0}$".format(column)) cb = basemap.colorbar(format=sfmt) # cb.ax.set_ylabel(infovar.get_units(var_name)) # plot the difference ax = fig.add_subplot(gs[1, column]) sel_axes.append(ax) ax.set_ylabel("$X_{0} - X_0$".format(column)) # #Mask only if the previous plot (means) is masked thediff = the_mean - control_mean if hasattr(to_plot, "mask"): to_plot = np.ma.masked_where(to_plot.mask, thediff) else: to_plot = thediff if var_name == "PR": # convert to mm/day to_plot = infovar.get_to_plot(var_name, to_plot, mask_oceans=False) vmin = np.ma.min(to_plot) vmax = np.ma.max(to_plot) d = max(abs(vmin), abs(vmax)) vmin = -d vmax = d field_norm, bounds, vmn_nice, vmx_nice = infovar.get_boundary_norm(vmin, vmax, diff_cmap.N, exclude_zero=False) basemap.pcolormesh(x, y, to_plot, cmap=diff_cmap, norm=field_norm, vmin=vmn_nice, vmax=vmx_nice) cb = basemap.colorbar(format=sfmt) t, pval = ttest_ind(means_for_years, control_means, axis=0) sig = pval < 0.1 basemap.contourf(x, y, sig.astype(int), nlevels=2, hatches=["+", None], colors="none") # cb.ax.set_ylabel(infovar.get_units(var_name)) # plot coastlines for the_ax in sel_axes: basemap.drawcoastlines(ax=the_ax, linewidth=common_plot_params.COASTLINE_WIDTH) # depends on the compared simulations and the months of interest fig_file_name = "compare_{0}_{1}_{2}_months-{3}.jpeg".format(var_name, control_label, "_".join(labels), "-".join([str(m) for m in months_of_interest])) figpath = os.path.join(images_folder, fig_file_name) fig.savefig(figpath, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight") plt.close(fig)
def _plot_row(axes, data, sim_label, var_name, increments=False, domain_props=None, season_list=None, significance=None): # data is a dict of season -> field # the field is a control mean in the case of the control mean # and the difference between the modified simulation and the control mean in the case of the modified simulation exclude_0_from_diff_colorbar = False assert isinstance(domain_props, DomainProperties) print("plotting row for {0}; increments = ({1})".format(var_name, increments)) lons2d, lats2d, basemap = domain_props.get_lon_lat_and_basemap() x, y = domain_props.x, domain_props.y vmin = None vmax = None # determine vmin and vmax for the row for season, field in data.items(): # field = _get_to_plot(var_name, field, lake_fraction=domain_props.lake_fraction, lons=lons2d, lats = lats2d) min_current, max_current = np.percentile(field[~field.mask], 1), np.percentile(field[~field.mask], 99) if vmin is None or min_current < vmin: vmin = min_current if vmax is None or max_current > vmax: vmax = max_current ncolors = 13 if exclude_0_from_diff_colorbar else 10 bounds = None if increments: # +1 to include white if vmin * vmax >= 0: if vmin >= 0: field_cmap = cm.get_cmap("YlOrBr_r", ncolors) else: field_cmap = cm.get_cmap("YlGnBu_r", ncolors) field_norm, bounds, bounds_min, bounds_max = infovar.get_boundary_norm(vmin, vmax, ncolors, exclude_zero=exclude_0_from_diff_colorbar, varname=var_name, difference=increments) else: field_cmap = cm.get_cmap("RdBu_r", ncolors) d = max(abs(vmin), abs(vmax)) field_norm, bounds, bounds_min, bounds_max = infovar.get_boundary_norm(-d, d, ncolors, exclude_zero=exclude_0_from_diff_colorbar, varname=var_name, difference=increments) else: # determine colorabr extent and spacing field_cmap, field_norm = infovar.get_colormap_and_norm_for(var_name, vmin=vmin, vmax=vmax, ncolors=ncolors) print("vmin = {0}; vmax = {1}".format(vmin, vmax)) col = 0 # axes[0].set_ylabel(sim_label) im = None for season in season_list: field = data[season] ax = axes[col] if not increments: # since the increments go below ax.set_title(season) else: mean_val = float("{0:.1e}".format(field.mean())) sf = ScalarFormatter(useMathText=True) sf.set_powerlimits((-2, 3)) # ax.set_title(r"$\Delta_{\rm mean} = " + sf.format_data(mean_val) + " $") basemap.drawmapboundary(ax=ax, fill_color="gray") im = basemap.pcolormesh(x, y, field, norm=field_norm, cmap=field_cmap, ax=ax) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) if significance is not None: cs = basemap.contourf(x, y, significance[season], levels=[0, 0.5, 1], colors="none", hatches=[None, ".."], ax=ax) # basemap.contour(x, y, significance[season], levels = [0.5, ], ax = ax, # linewidths = 0.5, colors="k") if col == 0 and False: # create a legend for the contour set artists, labels = cs.legend_elements() ax.legend([artists[-1], ], ["Significant changes \n with (p = 0.1)", ], handleheight=0.5, fontsize="x-small") col += 1 # plot the common colorbar if isinstance(field_norm, LogNorm): cb = plt.colorbar(im, cax=axes[-1]) else: cb = plt.colorbar(im, cax=axes[-1], extend="both", ticks=bounds) cb.ax.set_title(infovar.get_units(var_name))
def compare(paths=None, path_to_control_data=None, control_label="", labels=None, varnames=None, levels=None, months_of_interest=None, start_year=None, end_year=None): """ Comparing 2D fields :param paths: paths to the simulation results :param varnames: :param labels: Display name for each simulation (number of labels should be equal to the number of paths) :param path_to_control_data: the path with which the comparison done i.e. a in the following formula delta = (x - a)/a * 100% generates one image file per variable (in the folder images_for_lake-river_paper): compare_varname_<control_label>_<label1>_..._<labeln>_startyear_endyear.png """ # get coordinate data (assumes that all the variables and runs have the same coordinates) lons2d, lats2d, basemap = analysis.get_basemap_from_hdf( file_path=path_to_control_data) x, y = basemap(lons2d, lats2d) lake_fraction = analysis.get_array_from_file(path=path_to_control_data, var_name="lake_fraction") if lake_fraction is None: lake_fraction = np.zeros(lons2d.shape) ncolors = 10 # +1 to include white diff_cmap = cm.get_cmap("RdBu_r", ncolors + 1) for var_name, level in zip(varnames, levels): sfmt = infovar.get_colorbar_formatter(var_name) control_means = analysis.get_mean_2d_fields_for_months( path=path_to_control_data, var_name=var_name, months=months_of_interest, start_year=start_year, end_year=end_year, level=level) control_mean = np.mean(control_means, axis=0) fig = plt.figure() assert isinstance(fig, Figure) gs = gridspec.GridSpec(2, len(paths) + 1, wspace=0.5) # plot the control ax = fig.add_subplot(gs[0, 0]) assert isinstance(ax, Axes) ax.set_title("{0}".format(control_label)) ax.set_ylabel("Mean: $X_{0}$") to_plot = infovar.get_to_plot(var_name, control_mean, lake_fraction=lake_fraction, mask_oceans=True, lons=lons2d, lats=lats2d) # determine colorabr extent and spacing field_cmap, field_norm = infovar.get_colormap_and_norm_for( var_name, to_plot, ncolors=ncolors) basemap.pcolormesh(x, y, to_plot, cmap=field_cmap, norm=field_norm) cb = basemap.colorbar(format=sfmt) assert isinstance(cb, Colorbar) # cb.ax.set_ylabel(infovar.get_units(var_name)) units = infovar.get_units(var_name) info = "Variable:" \ "\n{0}" \ "\nPeriod: {1}-{2}" \ "\nMonths: {3}" \ "\nUnits: {4}" info = info.format( infovar.get_long_name(var_name), start_year, end_year, ",".join([ datetime(2001, m, 1).strftime("%b") for m in months_of_interest ]), units) ax.annotate(info, xy=(0.1, 0.3), xycoords="figure fraction") sel_axes = [ax] for the_path, the_label, column in zip(paths, labels, list(range(1, len(paths) + 1))): means_for_years = analysis.get_mean_2d_fields_for_months( path=the_path, var_name=var_name, months=months_of_interest, start_year=start_year, end_year=end_year) the_mean = np.mean(means_for_years, axis=0) # plot the mean value ax = fig.add_subplot(gs[0, column]) sel_axes.append(ax) ax.set_title("{0}".format(the_label)) to_plot = infovar.get_to_plot(var_name, the_mean, lake_fraction=lake_fraction, mask_oceans=True, lons=lons2d, lats=lats2d) basemap.pcolormesh(x, y, to_plot, cmap=field_cmap, norm=field_norm) ax.set_ylabel("Mean: $X_{0}$".format(column)) cb = basemap.colorbar(format=sfmt) # cb.ax.set_ylabel(infovar.get_units(var_name)) # plot the difference ax = fig.add_subplot(gs[1, column]) sel_axes.append(ax) ax.set_ylabel("$X_{0} - X_0$".format(column)) # #Mask only if the previous plot (means) is masked thediff = the_mean - control_mean if hasattr(to_plot, "mask"): to_plot = np.ma.masked_where(to_plot.mask, thediff) else: to_plot = thediff if var_name == "PR": # convert to mm/day to_plot = infovar.get_to_plot(var_name, to_plot, mask_oceans=False) vmin = np.ma.min(to_plot) vmax = np.ma.max(to_plot) d = max(abs(vmin), abs(vmax)) vmin = -d vmax = d field_norm, bounds, vmn_nice, vmx_nice = infovar.get_boundary_norm( vmin, vmax, diff_cmap.N, exclude_zero=False) basemap.pcolormesh(x, y, to_plot, cmap=diff_cmap, norm=field_norm, vmin=vmn_nice, vmax=vmx_nice) cb = basemap.colorbar(format=sfmt) t, pval = ttest_ind(means_for_years, control_means, axis=0) sig = pval < 0.1 basemap.contourf(x, y, sig.astype(int), nlevels=2, hatches=["+", None], colors="none") # cb.ax.set_ylabel(infovar.get_units(var_name)) # plot coastlines for the_ax in sel_axes: basemap.drawcoastlines( ax=the_ax, linewidth=common_plot_params.COASTLINE_WIDTH) # depends on the compared simulations and the months of interest fig_file_name = "compare_{0}_{1}_{2}_months-{3}.jpeg".format( var_name, control_label, "_".join(labels), "-".join([str(m) for m in months_of_interest])) figpath = os.path.join(images_folder, fig_file_name) fig.savefig(figpath, dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight") plt.close(fig)
def _plot_row(axes, data, sim_label, var_name, increments=False, domain_props=None, season_list=None, significance=None): # data is a dict of season -> field # the field is a control mean in the case of the control mean # and the difference between the modified simulation and the control mean in the case of the modified simulation exclude_0_from_diff_colorbar = False assert isinstance(domain_props, DomainProperties) print("plotting row for {0}; increments = ({1})".format( var_name, increments)) lons2d, lats2d, basemap = domain_props.get_lon_lat_and_basemap() x, y = domain_props.x, domain_props.y vmin = None vmax = None # determine vmin and vmax for the row for season, field in data.items(): # field = _get_to_plot(var_name, field, lake_fraction=domain_props.lake_fraction, lons=lons2d, lats = lats2d) min_current, max_current = np.percentile(field[~field.mask], 1), np.percentile( field[~field.mask], 99) if vmin is None or min_current < vmin: vmin = min_current if vmax is None or max_current > vmax: vmax = max_current ncolors = 13 if exclude_0_from_diff_colorbar else 10 bounds = None if increments: # +1 to include white if vmin * vmax >= 0: if vmin >= 0: field_cmap = cm.get_cmap("YlOrBr_r", ncolors) else: field_cmap = cm.get_cmap("YlGnBu_r", ncolors) field_norm, bounds, bounds_min, bounds_max = infovar.get_boundary_norm( vmin, vmax, ncolors, exclude_zero=exclude_0_from_diff_colorbar, varname=var_name, difference=increments) else: field_cmap = cm.get_cmap("RdBu_r", ncolors) d = max(abs(vmin), abs(vmax)) field_norm, bounds, bounds_min, bounds_max = infovar.get_boundary_norm( -d, d, ncolors, exclude_zero=exclude_0_from_diff_colorbar, varname=var_name, difference=increments) else: # determine colorabr extent and spacing field_cmap, field_norm = infovar.get_colormap_and_norm_for( var_name, vmin=vmin, vmax=vmax, ncolors=ncolors) print("vmin = {0}; vmax = {1}".format(vmin, vmax)) col = 0 # axes[0].set_ylabel(sim_label) im = None for season in season_list: field = data[season] ax = axes[col] if not increments: # since the increments go below ax.set_title(season) else: mean_val = float("{0:.1e}".format(field.mean())) sf = ScalarFormatter(useMathText=True) sf.set_powerlimits((-2, 3)) # ax.set_title(r"$\Delta_{\rm mean} = " + sf.format_data(mean_val) + " $") basemap.drawmapboundary(ax=ax, fill_color="gray") im = basemap.pcolormesh(x, y, field, norm=field_norm, cmap=field_cmap, ax=ax) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) if significance is not None: cs = basemap.contourf(x, y, significance[season], levels=[0, 0.5, 1], colors="none", hatches=[None, ".."], ax=ax) # basemap.contour(x, y, significance[season], levels = [0.5, ], ax = ax, # linewidths = 0.5, colors="k") if col == 0 and False: # create a legend for the contour set artists, labels = cs.legend_elements() ax.legend([ artists[-1], ], [ "Significant changes \n with (p = 0.1)", ], handleheight=0.5, fontsize="x-small") col += 1 # plot the common colorbar if isinstance(field_norm, LogNorm): cb = plt.colorbar(im, cax=axes[-1]) else: cb = plt.colorbar(im, cax=axes[-1], extend="both", ticks=bounds) cb.ax.set_title(infovar.get_units(var_name))
def validate_precip(model_file="", simlabel="", obs_manager=None, season_to_months=None, start_year=None, end_year=None, season_to_plot_indices=None, station_ids_list=None): """ :param model_file: :param obs_manager: should implement the method getMeanFieldForMonthsInterpolatedTo(self, months = None, lonsTarget = None, latsTarget = None) anusplin data is in mm/day model data is in m/s """ model_var_name = "PR" if obs_manager is None: print( "Skipping validation of {}, since the obs manager is None.".format( model_var_name)) return if station_ids_list is not None: # 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_list) else: stations = [] model_level = 0 reasonable_error_mm_per_day = 1 assert isinstance(obs_manager, AnuSplinManager) fig = plt.figure() assert isinstance(fig, Figure) fig.suptitle("({0}) - ({1})".format(simlabel, "Obs.")) lon, lat, basemap = analysis.get_basemap_from_hdf(file_path=model_file) # do calculations and only after that do the plotting season_to_field = {} # calculate global min and max for plotting vmin = None vmax = None for season, months in season_to_months.items(): model_field = analysis.get_seasonal_climatology( start_year=start_year, end_year=end_year, months=months, level=model_level, var_name=model_var_name, hdf_path=model_file) # convert m/s to mm/day for comparison with anusplin data model_field *= 1000.0 * 60 * 60 * 24 obs_field = obs_manager.getMeanFieldForMonthsInterpolatedTo( months=months, lonstarget=lon, latstarget=lat, start_year=start_year, end_year=end_year) # calculate the difference between the modelled and observed fields the_diff = model_field - obs_field current_min = np.min(the_diff) current_max = np.max(the_diff) if vmin is not None: vmin = current_min if current_min < vmin else vmin vmax = current_max if current_max > vmax else vmax else: vmin = current_min vmax = current_max season_to_field[season] = the_diff ncolors = 12 gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 0.05]) cmap = cm.get_cmap("RdBu_r", ncolors) x, y = basemap(lon, lat) im = None d = min(abs(vmin), abs(vmax)) vmin = -d vmax = d bn, bounds, _, _ = infovar.get_boundary_norm(vmin, vmax, ncolors, exclude_zero=False) print("bounds: ", bounds) cs = None for season, field in season_to_field.items(): row, col = season_to_plot_indices[season] ax = fig.add_subplot(gs[row, col]) ax.set_title(season) basemap.drawmapboundary(fill_color="gray", ax=ax) im = basemap.pcolormesh(x, y, season_to_field[season], vmin=vmin, vmax=vmax, cmap=cmap, norm=bn) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) for the_station in stations: assert isinstance(the_station, Station) xst, yst = basemap(the_station.longitude, the_station.latitude) # ax.annotate(the_station.id, (xst, yst), font_properties=FontProperties(size=6), # bbox=dict(facecolor="w"), va="top", ha="right") basemap.scatter(xst, yst, c="g", ax=ax) # small_error = (np.abs(season_to_field[season]) < reasonable_error_mm_per_day).astype(int) # nlevs = 1 # ax.contour(x, y, small_error, nlevs, colors = "black", linestyle = "-") # cs = ax.contourf(x, y, small_error, nlevs, colors="none", hatches=["/", None], extend="lower", linewidth=2) # artists, labels = cs.legend_elements() # plt.legend(artists, labels, handleheight=2) cax = fig.add_subplot(gs[:, 2]) cax.set_title("mm/day\n") plt.colorbar(im, cax=cax, extend="both") seasons_str = "_".join( sorted([str(s) for s in list(season_to_field.keys())])) atm_val_folder = os.path.join(images_folder, "validate_atm") if not os.path.isdir(atm_val_folder): os.mkdir(atm_val_folder) out_filename = "{3}/validate_2d_{0}_{1}_{2}.png".format( model_var_name, simlabel, seasons_str, atm_val_folder) fig.savefig(os.path.join(images_folder, out_filename), bbox_inches="tight")
def validate_temperature(model_file="", simlabel="", obs_manager=None, season_to_months=None, start_year=None, end_year=None, season_to_plot_indices=None, model_var_name="TT_max"): """ :param model_file: :param obs_manager: should implement the method getMeanFieldForMonthsInterpolatedTo(self, months = None, lonsTarget = None, latsTarget = None) anusplin data is in degrees Celsium model data is in deg C """ if obs_manager is None: print( "Skipping validation of {}, since the obs manager is None.".format( model_var_name)) return model_level = 0 reasonable_error_deg = 2 assert isinstance(obs_manager, AnuSplinManager) fig = plt.figure() assert isinstance(fig, Figure) fig.suptitle("({0}) - ({1})".format(simlabel, obs_manager.name)) lon, lat, basemap = analysis.get_basemap_from_hdf(file_path=model_file) # do calculations and only after that do the plotting season_to_field = {} # calculate global min and max for plotting vmin = None vmax = None for season, months in season_to_months.items(): model_field = analysis.get_seasonal_climatology( start_year=start_year, end_year=end_year, months=months, level=model_level, var_name=model_var_name, hdf_path=model_file) obs_field = obs_manager.getMeanFieldForMonthsInterpolatedTo( months=months, lonstarget=lon, latstarget=lat, start_year=start_year, end_year=end_year) # calculate the difference between the modelled and observed fields the_diff = model_field - obs_field current_min = np.min(the_diff) current_max = np.max(the_diff) if vmin is not None: vmin = current_min if current_min < vmin else vmin vmax = current_max if current_max > vmax else vmax else: vmin = current_min vmax = current_max season_to_field[season] = the_diff ncolors = 10 gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 0.05]) cmap = cm.get_cmap("RdBu_r", ncolors) x, y = basemap(lon, lat) im = None d = min(abs(vmin), abs(vmax)) vmin = -d vmax = d bn, bounds, _, _ = infovar.get_boundary_norm(vmin, vmax, ncolors) print("bounds: ", bounds) cs = None for season, field in season_to_field.items(): row, col = season_to_plot_indices[season] ax = fig.add_subplot(gs[row, col]) ax.set_title(season) im = basemap.pcolormesh(x, y, season_to_field[season], vmin=vmin, vmax=vmax, cmap=cmap, norm=bn) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) small_error = (np.abs(season_to_field[season]) < reasonable_error_deg).astype(int) nlevs = 1 # ax.contour(x, y, small_error, nlevs, colors = "black", linestyle = "-") cs = ax.contourf(x, y, small_error, nlevs, colors="none", hatches=["/", None], extend="lower", linewidth=2) # artists, labels = cs.legend_elements() # plt.legend(artists, labels, handleheight=2) cax = fig.add_subplot(gs[:, 2]) units_str = r"${\rm ^\circ}$" var_str = r"$T_{\max}$" if model_var_name.endswith( "_max") else r"$T_{\min}$" cax.set_title("{0}, {1}".format(var_str, units_str)) plt.colorbar(im, cax=cax, extend="both") seasons_str = "_".join( sorted([str(s) for s in list(season_to_field.keys())])) atm_val_folder = os.path.join(images_folder, "validate_atm") if not os.path.isdir(atm_val_folder): os.mkdir(atm_val_folder) out_filename = "{3}/validate_2d_{0}_{1}_{2}.png".format( model_var_name, simlabel, seasons_str, atm_val_folder) fig.savefig(os.path.join(images_folder, out_filename), dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight")
def validate_precip(model_file="", simlabel="", obs_manager=None, season_to_months=None, start_year=None, end_year=None, season_to_plot_indices=None, station_ids_list=None): """ :param model_file: :param obs_manager: should implement the method getMeanFieldForMonthsInterpolatedTo(self, months = None, lonsTarget = None, latsTarget = None) anusplin data is in mm/day model data is in m/s """ model_var_name = "PR" if obs_manager is None: print("Skipping validation of {}, since the obs manager is None.".format(model_var_name)) return if station_ids_list is not None: # 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_list ) else: stations = [] model_level = 0 reasonable_error_mm_per_day = 1 assert isinstance(obs_manager, AnuSplinManager) fig = plt.figure() assert isinstance(fig, Figure) fig.suptitle("({0}) - ({1})".format(simlabel, "Obs.")) lon, lat, basemap = analysis.get_basemap_from_hdf(file_path=model_file) # do calculations and only after that do the plotting season_to_field = {} # calculate global min and max for plotting vmin = None vmax = None for season, months in season_to_months.items(): model_field = analysis.get_seasonal_climatology(start_year=start_year, end_year=end_year, months=months, level=model_level, var_name=model_var_name, hdf_path=model_file) # convert m/s to mm/day for comparison with anusplin data model_field *= 1000.0 * 60 * 60 * 24 obs_field = obs_manager.getMeanFieldForMonthsInterpolatedTo(months=months, lonstarget=lon, latstarget=lat, start_year=start_year, end_year=end_year) # calculate the difference between the modelled and observed fields the_diff = model_field - obs_field current_min = np.min(the_diff) current_max = np.max(the_diff) if vmin is not None: vmin = current_min if current_min < vmin else vmin vmax = current_max if current_max > vmax else vmax else: vmin = current_min vmax = current_max season_to_field[season] = the_diff ncolors = 12 gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 0.05]) cmap = cm.get_cmap("RdBu_r", ncolors) x, y = basemap(lon, lat) im = None d = min(abs(vmin), abs(vmax)) vmin = -d vmax = d bn, bounds, _, _ = infovar.get_boundary_norm(vmin, vmax, ncolors, exclude_zero=False) print("bounds: ", bounds) cs = None for season, field in season_to_field.items(): row, col = season_to_plot_indices[season] ax = fig.add_subplot(gs[row, col]) ax.set_title(season) basemap.drawmapboundary(fill_color="gray", ax=ax) im = basemap.pcolormesh(x, y, season_to_field[season], vmin=vmin, vmax=vmax, cmap=cmap, norm=bn) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) for the_station in stations: assert isinstance(the_station, Station) xst, yst = basemap(the_station.longitude, the_station.latitude) # ax.annotate(the_station.id, (xst, yst), font_properties=FontProperties(size=6), # bbox=dict(facecolor="w"), va="top", ha="right") basemap.scatter(xst, yst, c="g", ax=ax) # small_error = (np.abs(season_to_field[season]) < reasonable_error_mm_per_day).astype(int) # nlevs = 1 # ax.contour(x, y, small_error, nlevs, colors = "black", linestyle = "-") # cs = ax.contourf(x, y, small_error, nlevs, colors="none", hatches=["/", None], extend="lower", linewidth=2) # artists, labels = cs.legend_elements() # plt.legend(artists, labels, handleheight=2) cax = fig.add_subplot(gs[:, 2]) cax.set_title("mm/day\n") plt.colorbar(im, cax=cax, extend="both") seasons_str = "_".join(sorted([str(s) for s in list(season_to_field.keys())])) atm_val_folder = os.path.join(images_folder, "validate_atm") if not os.path.isdir(atm_val_folder): os.mkdir(atm_val_folder) out_filename = "{3}/validate_2d_{0}_{1}_{2}.png".format(model_var_name, simlabel, seasons_str, atm_val_folder) fig.savefig(os.path.join(images_folder, out_filename), bbox_inches="tight")
def validate_temperature( model_file="", simlabel="", obs_manager=None, season_to_months=None, start_year=None, end_year=None, season_to_plot_indices=None, model_var_name="TT_max"): """ :param model_file: :param obs_manager: should implement the method getMeanFieldForMonthsInterpolatedTo(self, months = None, lonsTarget = None, latsTarget = None) anusplin data is in degrees Celsium model data is in deg C """ if obs_manager is None: print("Skipping validation of {}, since the obs manager is None.".format(model_var_name)) return model_level = 0 reasonable_error_deg = 2 assert isinstance(obs_manager, AnuSplinManager) fig = plt.figure() assert isinstance(fig, Figure) fig.suptitle("({0}) - ({1})".format(simlabel, obs_manager.name)) lon, lat, basemap = analysis.get_basemap_from_hdf(file_path=model_file) # do calculations and only after that do the plotting season_to_field = {} # calculate global min and max for plotting vmin = None vmax = None for season, months in season_to_months.items(): model_field = analysis.get_seasonal_climatology(start_year=start_year, end_year=end_year, months=months, level=model_level, var_name=model_var_name, hdf_path=model_file) obs_field = obs_manager.getMeanFieldForMonthsInterpolatedTo(months=months, lonstarget=lon, latstarget=lat, start_year=start_year, end_year=end_year) # calculate the difference between the modelled and observed fields the_diff = model_field - obs_field current_min = np.min(the_diff) current_max = np.max(the_diff) if vmin is not None: vmin = current_min if current_min < vmin else vmin vmax = current_max if current_max > vmax else vmax else: vmin = current_min vmax = current_max season_to_field[season] = the_diff ncolors = 10 gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 0.05]) cmap = cm.get_cmap("RdBu_r", ncolors) x, y = basemap(lon, lat) im = None d = min(abs(vmin), abs(vmax)) vmin = -d vmax = d bn, bounds, _, _ = infovar.get_boundary_norm(vmin, vmax, ncolors) print("bounds: ", bounds) cs = None for season, field in season_to_field.items(): row, col = season_to_plot_indices[season] ax = fig.add_subplot(gs[row, col]) ax.set_title(season) im = basemap.pcolormesh(x, y, season_to_field[season], vmin=vmin, vmax=vmax, cmap=cmap, norm=bn) basemap.drawcoastlines(ax=ax, linewidth=cpp.COASTLINE_WIDTH) small_error = (np.abs(season_to_field[season]) < reasonable_error_deg).astype(int) nlevs = 1 # ax.contour(x, y, small_error, nlevs, colors = "black", linestyle = "-") cs = ax.contourf(x, y, small_error, nlevs, colors="none", hatches=["/", None], extend="lower", linewidth=2) # artists, labels = cs.legend_elements() # plt.legend(artists, labels, handleheight=2) cax = fig.add_subplot(gs[:, 2]) units_str = r"${\rm ^\circ}$" var_str = r"$T_{\max}$" if model_var_name.endswith("_max") else r"$T_{\min}$" cax.set_title("{0}, {1}".format(var_str, units_str)) plt.colorbar(im, cax=cax, extend="both") seasons_str = "_".join(sorted([str(s) for s in list(season_to_field.keys())])) atm_val_folder = os.path.join(images_folder, "validate_atm") if not os.path.isdir(atm_val_folder): os.mkdir(atm_val_folder) out_filename = "{3}/validate_2d_{0}_{1}_{2}.png".format(model_var_name, simlabel, seasons_str, atm_val_folder) fig.savefig(os.path.join(images_folder, out_filename), dpi=cpp.FIG_SAVE_DPI, bbox_inches="tight")