def plot_2d(): positions = [[10, 90], [60, 5]] extents = [[30, -30], [30, 20]] colors = ['dodgerblue', 'crimson'] fig = plt.figure() fig.set_size_inches(5.5, 2.5) ax = fig.add_subplot(121) ax.set_xlim([0, 100]) ax.set_xticks([0, 25, 50, 75, 100]) ax.set_xlabel('width [mm]') ax.set_ylim([0, 100]) ax.set_ylabel('height [mm]') ax.set_yticks([0, 25, 50, 75, 100]) rect = patches.Rectangle((10, 90), 30, -30, alpha=0.25, facecolor="dodgerblue", edgecolor='k', lw=0.75, ls='--') ax.add_patch(rect) rect = patches.Rectangle((60, 5), 30, 20, alpha=0.25, facecolor="crimson", edgecolor='k', lw=0.75, ls='--') ax.add_patch(rect) ax.scatter([10, 60], [90, 5], marker=".", s=50, lw=0.25, facecolor="r", edgecolor='k') ax.plot([10, 40], [90, 90], lw=1.5, color='r') ax.plot([10, 10], [90, 60], lw=1.5, color='r') ax.plot([60, 60], [5, 25], lw=1.5, color='r') ax.plot([60, 90], [5, 5], lw=1.5, color='r') col_labels = ["Pos 1", "Pos 2"] rows_2d = ["width", "height"] cell_text = [[positions[0][0], positions[1][0]], [positions[0][1], positions[1][1]]] table = matplotlib.table.table(ax, cellText=cell_text, rowLabels=rows_2d, colLabels=col_labels, cellLoc="center", bbox=[1.6, 0.6, 0.4, 0.3], colWidths=[0.2 for c in col_labels], colColours=colors) ax.text(130, 100, "Positions DataArray") #, transform=ax.transAxes , fontsize=10) table.auto_set_font_size(False) table.set_fontsize(8) col_labels = ["Ext 1", "Ext 2"] cell_text = [[extents[0][0], extents[1][0]], [extents[0][1], extents[1][1]]] table = matplotlib.table.table(ax, cellText=cell_text, rowLabels=rows_2d, colLabels=col_labels, cellLoc="center", bbox=[1.6, 0.1, 0.4, 0.3], colWidths=[0.2 for c in col_labels], colColours=colors) ax.text(130, 100, "Positions DataArray") #, transform=ax.transAxes , fontsize=10) table.auto_set_font_size(False) table.set_fontsize(8) ax.text(130, 45, "Extents DataArray") #, transform=ax.transAxes , fontsize=10) ax.spines["top"].set_visible(False) ax.spines['right'].set_visible(False) fig.subplots_adjust(bottom=0.175, left=0.15, right=0.95, top=0.95) fig.savefig("../images/2d_mtag.png")
def make_water_quality_confidence_score_guide(png_path): """ Create table explaining confidence scores for water quality forecasts. This table is static. Args: png_path: Raw str. Path for PNG to be created Returns: None. Table is saved as a PNG to the specified path """ matplotlib.table.CustomCell = MyCell # Data for table grid data = [ ["None", "-", "< 0.2"], ["Very low", "< 25", "-"], ["Low", "25 - 50", "0.2 - 0.4"], ["Medium", "50 - 75", "0.4 - 0.6"], ["High", "> 75", "> 0.6"], ] cell_colours = [ ["lightgrey", "white", "lightgrey"], ["lightsalmon", "lightsalmon", "white"], ["yellow", "yellow", "yellow"], ["yellowgreen", "yellowgreen", "yellowgreen"], ["lightsteelblue", "lightsteelblue", "lightsteelblue"], ] # Build table col_labels = [ "Label", "Likelihood\n(%)", "Historic skill\n(MCC³)", ] table = plt.table( cellText=data, colLabels=col_labels, cellColours=cell_colours, loc="center", cellLoc="center", ) # Layout and basic formatting table.auto_set_font_size(False) table.auto_set_column_width(col=range(len(col_labels))) table.scale(1, 2.5) for (row, col), cell in table.get_celld().items(): if row == 0: cell.set_text_props(fontproperties=FontProperties(weight="bold")) cell.set_height(0.25) table.set_fontsize(20) plt.axis("off") plt.savefig(png_path, dpi=300, bbox_inches="tight")
def plot_3d(): positions = [[10, 10, 90], [60, 5, 20]] extents = [[30, 40, -30], [30, 60, 20]] colors = ['dodgerblue', 'crimson'] fig = plt.figure() fig.set_size_inches(5.5, 2.5) ax = plt.subplot2grid((2, 5), (0, 0), colspan=3, rowspan=2, projection='3d') ax.set_xlim([0, 100]) ax.set_xticks([0, 25, 50, 75, 100]) ax.set_xlabel('width [mm]') ax.set_ylim([0, 100]) ax.set_yticks([0, 25, 50, 75, 100]) ax.set_ylabel('depth [mm]') ax.set_zlabel('height [mm]') ax.set_zlim([0, 100]) ax.set_zticks([0, 25, 50, 75, 100]) for i in range(len(positions)): plotcubus(ax, positions[i], extents[i], colors[i]) col_labels = ["Pos 1", "Pos 2"] rows_3d = ["width", "height", "depth"] cell_text = [[positions[0][0], positions[1][0]], [positions[0][2], positions[1][2]], [positions[0][1], positions[1][1]]] table = matplotlib.table.table(ax, cellText=cell_text, rowLabels=rows_3d, colLabels=col_labels, cellLoc="center", bbox=[1.4, 0.5, 0.25, 0.3], colWidths=[0.1 for c in col_labels], colColours=colors) ax.text(170, 100, 130.0, "Positions DataArray") #, transform=ax.transAxes , fontsize=10) table.auto_set_font_size(False) table.set_fontsize(8) col_labels = ["Ext 1", "Ext 2"] cell_text = [[extents[0][0], extents[1][0]], [extents[0][2], extents[1][2]], [extents[0][1], extents[1][1]]] table = matplotlib.table.table(ax, cellText=cell_text, rowLabels=rows_3d, colLabels=col_labels, cellLoc="center", bbox=[1.4, -.1, 0.25, 0.3], colWidths=[0.1 for c in col_labels], colColours=colors) table.auto_set_font_size(False) table.set_fontsize(8) ax.text(180, 100, 5.0, "Extents DataArray") #, transform=ax.transAxes , fontsize=10) fig.subplots_adjust(bottom=0.1, left=0., right=0.95, top=0.95) fig.savefig("../images/3d_mtag.png")
def make_chla_forecast_table(fcst, rmse, cls_err, mcc, png_path): """ Make a summary table for chl-a. Args: fcst: Float. Predicted value rmse: Float. Hindcast root mean squared error cls_err: Float. Hindcast classification error (%) mcc: Float. Hindcast Matthews Correlation Coefficient png_path: Raw str. Path for PNG to be created Returns: None. Table is saved as a PNG to the specified path """ assert 0 <= cls_err <= 100, "'cls_err' must be between 0 and 100." assert mcc <= 1, "'mcc' cannot be greater than 1." matplotlib.table.CustomCell = MyCell # Get most likely class if fcst < 20: pred_class = "lower" else: pred_class = "upper" # Data for table grid (historic skill is "None" for all climate vars) data = [ [ wfd_class_dict[("chla", "lower")], "", "", "", "", "", "", ], [ wfd_class_dict[("chla", "upper")], "", "", "", "", "", "", ], ] # Build table col_labels = [ "WFD class", "Likelihood\nof class", f"Forecasted\nvalue\n({units_dict['chla']})", "RMSE\n(mg/l)¹", "Classification\nerror (%)²", "MCC³", "Forecast summary", ] table = plt.table( cellText=data, colLabels=col_labels, loc="center", cellLoc="center", ) # Layout and basic formatting table.auto_set_font_size(False) table.auto_set_column_width(col=range(len(col_labels))) table.scale(1, 6) for (row, col), cell in table.get_celld().items(): if row == 0: cell.set_text_props(fontproperties=FontProperties(weight="bold")) # Fake merged cells # Historic skill h = table.get_celld()[(0, 0)].get_height() w = table.get_celld()[(0, 0)].get_width() header = [table.add_cell(-1, pos, w, h, loc="center") for pos in [3, 4, 5]] [ cell.set_text_props(fontproperties=FontProperties(weight="bold")) for cell in header ] [cell.set_height(0.15) for cell in header] header[0].visible_edges = "TBL" header[1].visible_edges = "TB" header[2].visible_edges = "TBR" header[1].get_text().set_text("Historic skill*") # Stat cols lik = "Not available" for col, stat in enumerate([lik, fcst, rmse, cls_err, mcc], start=1): patch = [ table.add_cell(pos, col, w, h, loc="center") for pos in [1, 2] ] patch[0].visible_edges = "TLR" patch[1].visible_edges = "BLR" patch[0].get_text().set_text(f"\n\n{stat}") # Set colour just for MCC [cell.set_facecolor(assign_mcc_class(mcc)[1]) for cell in patch] # Forecast summary class_label = wfd_class_dict[("chla", pred_class)].split("(")[0][:-1] summary = (f"{names_dict['chla']} is expected\nto be " + "$\\bf{" + class_label.replace(" ", "\\ ") + "}$") conf = "Confidence level: $\\bf{Medium}$" # Always 'Medium'; See guidance doc patch = [table.add_cell(pos, 6, w, h, loc="center") for pos in [1, 2]] patch[0].visible_edges = "TLR" patch[1].visible_edges = "BLR" patch[0].get_text().set_text(summary) patch[1].get_text().set_text(conf) table.set_fontsize(20) plt.axis("off") plt.savefig(png_path, dpi=300, bbox_inches="tight")
def make_tp_cyano_colour_forecast_table(variable, lik_low, lik_hi, fcst, rmse, cls_err, mcc, png_path): """ Make a summary table for TP, cyano or colour. Args: variable: Str. Variable of interest. One of ['tp', 'cyano', 'colour'] lik_low: Float. Likelihood of lower class (probability between 0 and 1) lik_hi: Float. Likelihood of upper class (probability between 0 and 1) fcst: Float. Predicted value rmse: Float. Hindcast root mean squared error cls_err: Float. Hindcast classification error (%) mcc: Float. Hindcast Matthews Correlation Coefficient png_path: Raw str. Path for PNG to be created Returns: None. Table is saved as a PNG to the specified path """ assert 0 <= lik_low <= 1, "'lik_low' must be a probability between 0 and 1." assert 0 <= lik_hi <= 1, "'lik_hi' must be a probability between 0 and 1." assert 0 <= cls_err <= 100, "'cls_err' must be between 0 and 100." assert mcc <= 1, "'mcc' cannot be greater than 1." matplotlib.table.CustomCell = MyCell # Get most likely class if lik_low > lik_hi: pred_class = "lower" max_lik = lik_low else: pred_class = "upper" max_lik = lik_hi # Data for table grid (historic skill is "None" for all climate vars) data = [ [ wfd_class_dict[(variable, "lower")], assign_likelihood_label_water_quality(lik_low), "", "", "", "", "", ], [ wfd_class_dict[(variable, "upper")], assign_likelihood_label_water_quality(lik_hi), "", "", "", "", "", ], ] # Build table col_labels = [ "WFD class", "Likelihood\nof class", f"Forecasted\nvalue\n({units_dict[variable]})", f"RMSE\n({units_dict[variable]})¹", "Classification\nerror (%)²", "MCC³", "Forecast summary", ] table = plt.table( cellText=data, colLabels=col_labels, loc="center", cellLoc="center", ) # Layout and basic formatting table.auto_set_font_size(False) table.auto_set_column_width(col=range(len(col_labels))) table.scale(1, 6) for (row, col), cell in table.get_celld().items(): if row == 0: cell.set_text_props(fontproperties=FontProperties(weight="bold")) table[(1, 1)].set_facecolor( colour_dict[assign_likelihood_label_water_quality(lik_low)[0]]) table[(2, 1)].set_facecolor( colour_dict[assign_likelihood_label_water_quality(lik_hi)[0]]) # Fake merged cells # Historic skill h = table.get_celld()[(0, 0)].get_height() w = table.get_celld()[(0, 0)].get_width() header = [table.add_cell(-1, pos, w, h, loc="center") for pos in [3, 4, 5]] [ cell.set_text_props(fontproperties=FontProperties(weight="bold")) for cell in header ] [cell.set_height(0.15) for cell in header] header[0].visible_edges = "TBL" header[1].visible_edges = "TB" header[2].visible_edges = "TBR" header[1].get_text().set_text("Historic skill*") # Stat cols for col, stat in enumerate([fcst, rmse, cls_err, mcc], start=2): patch = [ table.add_cell(pos, col, w, h, loc="center") for pos in [1, 2] ] patch[0].visible_edges = "TLR" patch[1].visible_edges = "BLR" patch[0].get_text().set_text(f"\n\n{stat}") # Set colour just for MCC [cell.set_facecolor(assign_mcc_class(mcc)[1]) for cell in patch] # Forecast summary class_label = wfd_class_dict[(variable, pred_class)].split("(")[0][:-1] summary = (f"{names_dict[variable]} is expected\nto be " + "$\\bf{" + class_label.replace(" ", "\\ ") + "}$") conf = get_overall_confidence( assign_likelihood_label_water_quality(max_lik), assign_mcc_class(mcc)[0]) conf = "Confidence level: $\\bf{" + conf + "}$" patch = [table.add_cell(pos, 6, w, h, loc="center") for pos in [1, 2]] patch[0].visible_edges = "TLR" patch[1].visible_edges = "BLR" patch[0].get_text().set_text(summary) patch[1].get_text().set_text(conf) table.set_fontsize(20) plt.axis("off") plt.savefig(png_path, dpi=300, bbox_inches="tight")