def plot_boundary_heads(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) def process_dtw_obs(fpth): v = np.genfromtxt(fpth, names=True, delimiter=",") v["time"] /= 365.25 v["time"] += 1908.353182752 for key in v.dtype.names[1:]: v[key] *= -1.0 return v name = list(parameters.keys())[0] pth = os.path.join(ws, name, "{}.gwf.obs.csv".format(name)) hdata = process_dtw_obs(pth) pheads = ("HD01", "HD12", "HD14") hlabels = ("Upper aquifer", "Middle aquifer", "Lower aquifer") hcolors = ("green", "cyan", "blue") fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6.8, 6.8 / 3)) ax.set_xlim(1907, 2007) ax.set_xticks(xticks) ax.set_ylim(50.0, -10.0) ax.set_yticks(sorted([50.0, 40.0, 30.0, 20.0, 10.0, 0.0, -10.0])) ax.plot([1907, 2007], [0, 0], lw=0.5, color="0.5") for idx, key in enumerate(pheads): ax.plot( hdata["time"], hdata[key], lw=0.75, color=hcolors[idx], label=hlabels[idx], ) fs.graph_legend(ax=ax, frameon=False) ax.set_ylabel("Depth to water, in {}".format(length_units)) ax.set_xlabel("Year") fs.remove_edge_ticks(ax=ax) fig.tight_layout() # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_grid(sim): fs = USGSFigure(figure_type="map", verbose=False) sim_ws = os.path.join(ws, sim_name) gwf = sim.get_model(sim_name) fig = plt.figure(figsize=figure_size) fig.tight_layout() # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) head = hobj.get_data() # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") spdis = cobj.get_data(text="DATA-SPDIS", totim=1.0) ax = fig.add_subplot(1, 1, 1, aspect="equal") pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={"row": 0}) # pxs.plot_grid() pxs.plot_bc(name="CHD") pxs.plot_array(head, cmap="jet") levels = np.arange(-1, 1, 0.1) cs = pxs.contour_array(head, levels=levels, colors="k", linewidths=1.0, linestyles="-") pxs.plot_specific_discharge(spdis, normalize=False, kstep=5, hstep=5) ax.set_xlabel("x position (m)") ax.set_ylabel("z position (m)") ax.set_ylim(-3, 0) fs.remove_edge_ticks(ax) plt.clabel(cs, fmt="%3.1f", fontsize=5) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) fig.savefig(fpth) return
def plot_compaction(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name fig, axes = plt.subplots( ncols=2, nrows=3, figsize=figure_size, sharex=True, constrained_layout=True, ) axes = axes.flatten() idx = 0 ax = axes[idx] ax.set_xlim(0, 120) ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Interbed compaction", compaction_heading[0]) fs.heading(ax, letter="A", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) fs.graph_legend(ax, ncol=2, loc="upper center") ht = "{} {}".format("Interbed compaction", compaction_heading[1]) fs.heading(ax, letter="B", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Coarse-grained compaction", compaction_heading[0]) fs.heading(ax, letter="C", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Coarse-grained compaction", compaction_heading[1]) fs.heading(ax, letter="D", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Total compaction", compaction_heading[0]) fs.heading(ax, letter="E", heading=ht) fs.remove_edge_ticks(ax) ax.set_ylabel(" ") ax.set_xlabel(" ") idx += 1 ax = axes.flat[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Total compaction", compaction_heading[1]) fs.heading(ax, letter="F", heading=ht) fs.remove_edge_ticks(ax) ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[]) ax.set_ylabel( "Downward vertical displacement at the top of the model layer, in meters" ) ax.set_xlabel("Simulation time, in years") # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-02{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_effstress(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name # get effective stress csub observations gwf = sim.get_model(name) cobs = gwf.csub.output.obs().data # get head-based csub observations name0 = name.replace("-p02b", "-p02a") ws0 = os.path.join(ws, name0) sim0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0) gwf0 = sim0.get_model(name0) cobs0 = gwf0.csub.output.obs().data # calculate normalized simulation time tpct = cobs["totim"] * 100 / tau0 # plot the results fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(1, 2, figure=fig) idx = 0 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * cobs0["TCOMP"] / skv, lw=0, marker=".", ms=3, color="#238A8DFF", label="Head-based", ) ax.plot( tpct, 100 * cobs["TCOMP"] / skv, lw=0.75, label="Effective stress-based", color="black", zorder=100, ) leg = fs.graph_legend(ax, loc="lower right") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel("Compaction, in percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 100) fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) idx += 1 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * (cobs0["TCOMP"] - cobs["TCOMP"]) / skv, lw=1, ls=":", color="black", ) ax.set_xticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel( "Head-based minus effective stress-based\nsubsidence, in percent of ultimate value" ) ax.set_xlim(0, 100) fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_grid(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) name = sim.name gwf = sim.get_model(name) fig, ax = plt.subplots(figsize=(6.8, 2.0)) mc = flopy.plot.PlotCrossSection(model=gwf, line={"Row": 0}, ax=ax) ax.fill_between([0, 1], y1=0, y2=botm, color="cyan", alpha=0.5) fs.add_text( ax=ax, text="Constant head", x=0.5, y=-500.0, bold=False, italic=False, transform=False, va="center", ha="center", fontsize=9, ) ax.fill_between([2, 3], y1=0, y2=botm, color="cyan", alpha=0.5) fs.add_text( ax=ax, text="Constant head", x=2.5, y=-500.0, bold=False, italic=False, transform=False, va="center", ha="center", fontsize=9, ) ax.fill_between([1, 2], y1=-499.5, y2=-500.5, color="brown", alpha=0.5) fs.add_annotation( ax=ax, text="Delay interbed", xy=(1.5, -510.0), xytext=(1.6, -300), bold=False, italic=False, fontsize=9, ha="center", va="center", zorder=100, arrowprops=arrow_props, ) mc.plot_grid(color="0.5", lw=0.5, zorder=100) ax.set_xlim(0, 3) ax.set_ylabel("Elevation, in meters") ax.set_xlabel("x-coordinate, in meters") fs.remove_edge_ticks(ax) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_grid(gwf, silent=True): fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure(figsize=figure_size, constrained_layout=False) gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5) plt.axis("off") axes = [] axes.append(fig.add_subplot(gs[:6, :5])) axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0])) for ax in axes: ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # ax.set_xticks(ticklabels) # ax.set_yticks(ticklabels) # legend axis axes.append(fig.add_subplot(gs[6:, :])) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) top_coll = mm.plot_array(top, vmin=1000, vmax=1120, masked_values=masked_values, alpha=0.5) mm.plot_bc("SFR", color="green") cv = mm.contour_array( top, levels=np.arange(1000, 1100, 20), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") cbar = plt.colorbar( top_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Land surface elevation, $ft$") ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.heading(ax, heading="Land surface elevation", idx=0) fs.remove_edge_ticks(ax) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) bot_coll = mm.plot_array(botm, vmin=500, vmax=1000, masked_values=masked_values, alpha=0.5) mm.plot_bc("GHB", color="purple") mm.plot_bc("WEL", color="red", kper=1) cv = mm.contour_array( botm, levels=np.arange(600, 1000, 100), linewidths=0.5, linestyles=":", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") cbar = plt.colorbar( bot_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Bottom elevation, $ft$") ax.set_xlabel("x-coordinate, in feet") fs.heading(ax, heading="Bottom elevation", idx=1) fs.remove_edge_ticks(ax) # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="0.5", mec="black", markeredgewidth=0.5, label="Inactive cells", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="green", mec="black", markeredgewidth=0.5, label="Stream boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="purple", mec="black", markeredgewidth=0.5, label="General head boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="red", mec="black", markeredgewidth=0.5, label="Well boundary", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color="black", label=r"Land surface elevation contour, $ft$", ) ax.plot( -10000, -10000, lw=0.5, ls=":", color="black", label=r"Bottom elevation contour, $ft$", ) fs.graph_legend(ax, loc="center", ncol=3) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_vertical_head(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = list(parameters.keys())[1] pth = os.path.join(ws, name, "{}.gwf.obs.csv".format(name)) df_heads, col_list = process_sim_csv( pth, origin_str="1908-05-09 00:00:00.000000" ) df_heads_year = df_heads.groupby(df_heads.index.year).mean() def get_colors(vmax=6): # set color cmap = plt.get_cmap("viridis") cNorm = mpl.colors.Normalize(vmin=0, vmax=vmax) scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap) colors = [] for ic in range(vmax): colors.append(scalarMap.to_rgba(ic)) return colors def build_head_data(df, year=1908): dfr = df.loc[df.index == year] xlabel = None x = [] y = [] for k in range(14): tag = "HD{:02d}".format(k + 1) h = dfr[tag].values[0] if k == 0: z0 = -25.0 xlabel = -1.0 * h else: z0 = zelevs[k] z1 = zelevs[k + 1] h *= -1.0 x += [h, h] y += [-z0, -z1] return xlabel, x, y iyears = (1908, 1916, 1926, 1936, 1946, 1956, 1966, 1976, 1986, 1996, 2006) colors = get_colors(vmax=len(iyears) - 1) xrange = (-10, 50) fig, ax = plt.subplots( nrows=1, ncols=1, sharey=True, figsize=(0.75 * 6.8, 4.0) ) ax.set_xlim(xrange) ax.set_ylim(-botm[-1], 0) for z in botm: ax.axhline(y=-z, xmin=-30, xmax=160, lw=0.5, color="0.5") # add confining units label = "" for k in (1, 2, 3): label = set_label(label, text="Confining unit") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="brown", lw=0, label=label ) ypos = -0.5 * (zelevs[2] + zelevs[3]) ax.text( 40, ypos, "Confining unit", ha="left", va="center", size=8, color="white", ) label = "" for k in (7, 8, 9): label = set_label(label, text="Thick aquitard") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="tan", lw=0, label=label ) ypos = -0.5 * (zelevs[8] + zelevs[9]) ax.text( 40, ypos, "Thick aquitard", ha="left", va="center", size=8, color="white", ) zo = 105 for idx, iyear in enumerate(iyears[:-1]): xlabel, x, y = build_head_data(df_heads_year, year=iyear) xlabel1, x1, y1 = build_head_data(df_heads_year, year=iyears[idx + 1]) ax.fill_betweenx( y, x, x2=x1, color=colors[idx], zorder=zo, step="mid", lw=0 ) ax.plot(x, y, lw=0.5, color="black", zorder=201) ax.text( xlabel, 24, "{}".format(iyear), ha="center", va="bottom", rotation=90, size=7, ) if iyear == 1996: ax.plot(x1, y1, lw=0.5, color="black", zorder=zo) ax.text( xlabel1, 24, "{}".format(iyears[idx + 1]), ha="center", va="bottom", rotation=90, size=7, ) zo += 1 # add layer labels for k in llabels: print_label(ax, edges, k) constant_heads(ax, annotate=True, xrange=xrange) ax.set_xlabel("Depth to water, in meters below land surface") ax.set_ylabel("Depth below land surface, in meters") fs.remove_edge_ticks(ax) fig.tight_layout(pad=0.5) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-04{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_head_es_comparison(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = list(parameters.keys())[0] pth = os.path.join(ws, name, "{}.csub.obs.csv".format(name)) hb = process_csub_obs(pth) name = list(parameters.keys())[1] pth = os.path.join(ws, name, "{}.csub.obs.csv".format(name)) es = process_csub_obs(pth) ymin = (2.0, 1, 1, 1, 0.1, 0.1) me = {} for idx, key in enumerate(pcomp): v = (es[key] - hb[key]).mean() me[key] = v fig, axes = plt.subplots(nrows=6, ncols=1, sharex=True, figsize=(6.8, 4.7)) for idx, key in enumerate(pcomp): label = clabels[idx] ax = axes[idx] ax.set_xlim(1907, 2007) ax.set_ylim(0, ymin[idx]) ax.set_xticks(xticks) stext = "none" otext = "none" if idx == 0: stext = "Effective stress-based" otext = "Head-based" mtext = "mean error = {:7.4f} {}".format(me[key], length_units) ax.plot(hb["time"], hb[key], color="#238A8DFF", lw=1.25, label=otext) ax.plot( es["time"], es[key], color="black", lw=0.75, label=stext, zorder=101, ) ltext = chr(ord("A") + idx) htext = "{}".format(label) fs.heading(ax, letter=ltext, heading=htext) va = "bottom" ym = 0.15 if idx in [2, 3]: va = "top" ym = 0.85 ax.text( 0.99, ym, mtext, ha="right", va=va, transform=ax.transAxes, fontsize=7, ) fs.remove_edge_ticks(ax=ax) if idx == 0: fs.graph_legend(ax, loc="center left", ncol=2) if idx == 5: ax.set_xlabel("Year") axp1 = fig.add_subplot(1, 1, 1, frameon=False) axp1.tick_params( labelcolor="none", top="off", bottom="off", left="off", right="off" ) axp1.set_xlim(0, 1) axp1.set_xticks([0, 1]) axp1.set_ylim(0, 1) axp1.set_yticks([0, 1]) axp1.set_ylabel("Compaction, in {}".format(length_units)) axp1.yaxis.set_label_coords(-0.05, 0.5) fs.remove_edge_ticks(ax) fig.tight_layout(pad=0.0001) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-02{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_regional_grid(silent=True): if silent: verbosity = 0 else: verbosity = 1 name = list(parameters.keys())[0] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load( sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity ) gwf = sim.get_model(sim_name) # get regional heads for constant head boundaries h = gwf.output.head().get_data() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(6.3, 3.5), ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 6))] # legend axis axes.append(fig.add_subplot(nrows, ncols, (7, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotCrossSection(gwf, ax=ax, line={"row": 0}) ca = mm.plot_array(h, head=h) mm.plot_bc("CHD", color="cyan", head=h) mm.plot_grid(lw=0.5, color="0.5") cv = mm.contour_array( h, levels=np.arange(0, 6, 0.5), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.1f") ax.plot( [50, 150, 150, 50, 50], [10, 10, aq_bottom, aq_bottom, 10], lw=1.25, color="#39FF14", ) fs.remove_edge_ticks(ax) ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("Elevation, in feet") # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="none", mec="0.5", markeredgewidth=0.5, label="Grid cell", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="0.5", markeredgewidth=0.5, label="Constant head", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="none", mec="#39FF14", markeredgewidth=1.25, label="Local model domain", ) ax.plot( -10000, -10000, lw=0.5, color="black", label="Head contour, $ft$", ) cbar = plt.colorbar(ca, shrink=0.5, orientation="horizontal", ax=ax) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $ft$", fontsize=9) fs.graph_legend(ax, loc="lower center", ncol=4) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-regional-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_results(idx, sim, silent=True): verbose = not silent if config.plotModel: fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[idx] sim_ws = os.path.join(ws, name) gwf = sim.get_model(sim_name) bot = gwf.dis.botm.array if idx == 0: plot_grid(gwf, silent=silent) plot_recharge(gwf, silent=silent) # create MODFLOW 6 head object hobj = gwf.output.head() # get times times = hobj.get_times() # extract heads and specific discharge head = hobj.get_data(totim=times[0]) imask = head <= bot + 0.001 head[imask] = -1e30 sat_thick = head - botm sat_thick[imask] = -1e30 # Create figure for simulation fig, axes = create_figure(nsubs=2, size=figure_size) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) h_coll = mm.plot_array(head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10) cv = mm.contour_array( head, masked_values=masked_values, levels=vlevels, linewidths=0.5, linestyles="-", colors=vcolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) cbar = plt.colorbar( h_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Water level, $m$") ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) s_coll = mm.plot_array( sat_thick, vmin=smin, vmax=smax, masked_values=masked_values, zorder=10, ) cv = mm.contour_array( sat_thick, masked_values=masked_values, levels=slevels, linewidths=0.5, linestyles=":", colors=scolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) cbar = plt.colorbar( s_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Saturated thickness, $m$") ax.set_xlabel("x-coordinate, in meters") # ax.set_ylabel("y-coordinate, in meters") fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) # create legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color=vcolor, label="Head contour, m", ) ax.plot( -10000, -10000, lw=0.5, ls=":", color=scolor, label="Saturated thickness contour, m", ) fs.graph_legend(ax, loc="center", ncol=3) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{:02d}{}".format(sim_name, idx + 2, config.figure_ext), ) fig.savefig(fpth)
def plot_recharge(gwf, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) fig, axes = create_figure(nsubs=2, size=figure_size) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) rch_coll = mm.plot_array(rch_high) mm.plot_bc("CHD", color="cyan") cv = mm.contour_array( rch_high, levels=[1e-6, 2e-6, 3e-6, 4e-6, 5e-6, 6e-6, 7e-6], linewidths=0.5, linestyles="-", colors="black", ) plt.clabel(cv, fmt="%1.0e") cbar = plt.colorbar( rch_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0e", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Recharge rate, $m/day$") ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) rch_coll = mm.plot_array(rch_low) mm.plot_bc("CHD", color="cyan") cv = mm.contour_array( rch_low, levels=[1e-9, 2e-9, 3e-9, 4e-9, 5e-9, 6e-9, 7e-9], linewidths=0.5, linestyles="-", colors="black", ) plt.clabel(cv, fmt="%1.0e") cbar = plt.colorbar( rch_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0e", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Recharge rate, $m/day$") ax.set_xlabel("x-coordinate, in meters") fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color=bcolor, label=r"Recharge rate contour, $m/day$", ) fs.graph_legend(ax, loc="center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_results(silent=True): if config.plotModel: verbose = not silent if silent: verbosity_level = 0 else: verbosity_level = 1 fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[0] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load(sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level) gwf = sim.get_model(sim_name) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") # extract heads head = hobj.get_data(totim=1) # plot grid fig = plt.figure(figsize=(6.8, 3.5), constrained_layout=True) gs = mpl.gridspec.GridSpec(nrows=8, ncols=10, figure=fig, wspace=5) plt.axis("off") ax = fig.add_subplot(gs[:7, 0:7]) ax.set_aspect("equal") mm = flopy.plot.PlotMapView(model=gwf, ax=ax) mm.plot_bc(ftype="WEL", kper=1, plotAll=True) mm.plot_bc(ftype="RIV", color="green", plotAll=True) mm.plot_grid(lw=0.5, color="0.5") ax.set_ylabel("y-coordinate, in feet") ax.set_xlabel("x-coordinate, in feet") fs.heading(ax, letter="A", heading="Map view") fs.remove_edge_ticks(ax) ax = fig.add_subplot(gs[:5, 7:]) mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={"row": 7}) mm.plot_array(np.ones((nlay, nrow, ncol)), head=head, cmap="jet") mm.plot_bc(ftype="WEL", kper=1) mm.plot_bc(ftype="RIV", color="green", head=head) mm.plot_grid(lw=0.5, color="0.5") ax.set_ylabel("Elevation, in feet") ax.set_xlabel("x-coordinate along model row 8, in feet") fs.heading(ax, letter="B", heading="Cross-section view") fs.remove_edge_ticks(ax) # items for legend ax = fig.add_subplot(gs[7, :]) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="River", ) ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) ax.plot( -1000, -1000, "s", ms=5, color="blue", mec="black", mew=0.5, label="Steady-state water table", ) fs.graph_legend( ax, ncol=3, frameon=False, loc="upper center", ) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) # figure with wetdry array fig = plt.figure(figsize=(4.76, 3), constrained_layout=True) ax = fig.add_subplot(1, 1, 1) ax.set_aspect("equal") mm = flopy.plot.PlotMapView(model=gwf, ax=ax) wd = mm.plot_array(wetdry_layer0) mm.plot_grid(lw=0.5, color="0.5") cbar = plt.colorbar(wd, shrink=0.5) cbar.ax.set_ylabel("WETDRY parameter") ax.set_ylabel("y-coordinate, in feet") ax.set_xlabel("x-coordinate, in feet") fs.remove_edge_ticks(ax) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(sim_name, config.figure_ext)) fig.savefig(fpth) # plot simulated rewetting results plot_simulated_results(2, gwf, hobj, cobj) # plot simulated newton results name = list(parameters.keys())[1] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load(sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level) gwf = sim.get_model(sim_name) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") # plot the newton results plot_simulated_results(3, gwf, hobj, cobj)
def plot_simulated_results(num, gwf, ho, co, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) botm_arr = gwf.dis.botm.array fig = plt.figure(figsize=(6.8, 6), constrained_layout=False) gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5) plt.axis("off") ax1 = fig.add_subplot(gs[:3, :5]) ax2 = fig.add_subplot(gs[:3, 5:], sharey=ax1) ax3 = fig.add_subplot(gs[3:6, :5], sharex=ax1) ax4 = fig.add_subplot(gs[3:6, 5:], sharex=ax1, sharey=ax1) ax5 = fig.add_subplot(gs[6, :]) axes = [ax1, ax2, ax3, ax4, ax5] labels = ("A", "B", "C", "D") aquifer = ("Upper aquifer", "Lower aquifer") cond = ("natural conditions", "pumping conditions") vmin, vmax = -10, 140 masked_values = [1e30, -1e30] levels = [ np.arange(0, 130, 10), (10, 20, 30, 40, 50, 55, 60), ] plot_number = 0 for idx, totim in enumerate(( 1, 2, )): head = ho.get_data(totim=totim) head[head < botm_arr] = -1e30 spdis = co.get_data(text="DATA-SPDIS", kstpkper=(0, totim - 1)) for k in range(nlay): ax = axes[plot_number] ax.set_aspect("equal") mm = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=k) mm.plot_grid(lw=0.5, color="0.5") cm = mm.plot_array(head, masked_values=masked_values, vmin=vmin, vmax=vmax) mm.plot_bc(ftype="WEL", kper=totim - 1) mm.plot_bc(ftype="RIV", color="green", kper=0) mm.plot_specific_discharge(spdis, normalize=True, color="0.75") cn = mm.contour_array( head, masked_values=masked_values, levels=levels[idx], colors="black", linewidths=0.5, ) plt.clabel(cn, fmt="%3.0f") heading = "{} under {}".format(aquifer[k], cond[totim - 1]) fs.heading(ax, letter=labels[plot_number], heading=heading) fs.remove_edge_ticks(ax) plot_number += 1 # set axis labels ax1.set_ylabel("y-coordinate, in feet") ax3.set_ylabel("y-coordinate, in feet") ax3.set_xlabel("x-coordinate, in feet") ax4.set_xlabel("x-coordinate, in feet") # legend ax = axes[-1] ax.set_ylim(1, 0) ax.set_xlim(-5, 5) ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) # items for legend ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="River", ) ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) ax.plot( -1000, -1000, "s", ms=5, color="none", mec="black", mew=0.5, label="Dry cell", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) ax.plot( -1000, -1000, lw=0.5, color="black", label="Head, in feet", ) fs.graph_legend( ax, ncol=5, frameon=False, loc="upper center", ) cbar = plt.colorbar(cm, ax=ax, shrink=0.5, orientation="horizontal") cbar.ax.set_xlabel("Head, in feet") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{:02d}{}".format(sim_name, num, config.figure_ext), ) fig.savefig(fpth)
def plot_grid(gwf, silent=True): sim_ws = os.path.join(ws, sim_name) # create lake array ilake = gwf.dis.idomain.array ilake[ilake == 0] = 100 ilake[ilake == 1] = 0 ilake[ilake == 100] = 1 for k in range(nlay): for i in range(16, nrow): for j in range(ncol): if ilake[k, i, j] == 1: ilake[k, i, j] = 2 # get edges and centers of cells xedges, yedges = gwf.modelgrid.xyedges[0], gwf.modelgrid.xyedges[1] xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1] # create sfr network poly0 = [ [xcenters[4], yedges[1]], [xcenters[4], ycenters[4]], [xcenters[7], ycenters[4]], [xcenters[7], yedges[6]], ] poly1 = [ [xcenters[8], yedges[11]], [xcenters[8], yedges[13]], [xcenters[9], yedges[14]], [xcenters[9], yedges[16]], ] poly2 = [ [xcenters[9], yedges[21]], [xcenters[9], ycenters[22]], [xedges[16], ycenters[22]], ] parts = [poly0, poly1, poly2] shape_pth = os.path.join(ws, sim_name, "sfr.shp") w = shp.Writer(target=shape_pth, shapeType=shp.POLYLINE) w.field("no", "C") w.line([poly0]) w.record(["1"]) w.line([poly1]) w.record(["2"]) w.line([poly2]) w.record(["3"]) w.close() sfr = shp.Reader(shape_pth) # load the observations fpth = os.path.join(ws, sim_name, "{}.lak.obs.csv".format(sim_name)) lak_results = np.genfromtxt(fpth, delimiter=",", names=True) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") kstpkper = hobj.get_kstpkper() head = hobj.get_data(kstpkper=kstpkper[0]) spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0]) # add lake stage to heads head[ilake == 1] = lak_results["LAKE1"][-1] head[ilake == 2] = lak_results["LAKE2"][-1] # observation locations p1 = (xcenters[3], ycenters[3]) p2 = (xcenters[8], ycenters[13]) p3 = (xcenters[13], ycenters[23]) # lake text locations pl1 = (xcenters[8], ycenters[8]) pl2 = (xcenters[8], ycenters[18]) fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(4, 6.9), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 8))] for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (9, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) mm.plot_bc("CHD", color="cyan") for shape in sfr.shapeRecords(): x = [i[0] for i in shape.shape.points[:]] y = [i[1] for i in shape.shape.points[:]] ax.plot(x, y, color="#3BB3D0", lw=1.5, zorder=1) mm.plot_inactive(color_noflow="#5DBB63") mm.plot_grid(lw=0.5, color="black") cv = mm.contour_array( head, levels=np.arange(120, 160, 5), linewidths=0.75, linestyles="-", colors="blue", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_specific_discharge(spdis, normalize=True, color="0.75") ax.plot(p1[0], p1[1], marker="o", mfc="red", mec="black", ms=4) ax.plot(p2[0], p2[1], marker="o", mfc="red", mec="black", ms=4) ax.plot(p3[0], p3[1], marker="o", mfc="red", mec="black", ms=4) ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.add_text( ax, "A", x=p1[0] + 150, y=p1[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.add_text( ax, "B", x=p2[0] + 150, y=p2[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.add_text( ax, "C", x=p3[0] + 150, y=p3[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.add_text( ax, "Lake 1", x=pl1[0], y=pl1[1], transform=False, italic=False, color="white", ha="center", va="center", ) fs.add_text( ax, "Lake 2", x=pl2[0], y=pl2[1], transform=False, italic=False, color="white", ha="center", va="center", ) fs.remove_edge_ticks(ax) # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="#5DBB63", mec="black", markeredgewidth=0.5, label="Lake boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="black", markeredgewidth=0.5, label="Constant-head boundary", ) ax.plot( -10000, -10000, lw=1.5, color="#3BB3D0", label="Stream network", ) ax.plot( -10000, -10000, lw=0, marker="o", ms=4, mfc="red", mec="black", markeredgewidth=0.5, label="Observation well", ) ax.plot( -10000, -10000, lw=0.75, ls="-", color="blue", label=r"Head contour, $ft$", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) fs.graph_legend(ax, loc="lower center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_results(silent=True): verbose = not silent if verbose: verbosity_level = 1 else: verbosity_level = 0 if config.plotModel: fs = USGSFigure(figure_type="map", verbose=verbose) # load the newton model name = list(parameters.keys())[0] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load(sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level) gwf = sim.get_model(sim_name) bot = gwf.dis.botm.array xnode = gwf.modelgrid.xcellcenters[0, :] # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # get a list of times times = hobj.get_times() # load rewet model name = list(parameters.keys())[1] sim_ws = os.path.join(ws, name) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj1 = flopy.utils.HeadFile(fpth) # Create figure for simulation fig, axes = plt.subplots( ncols=1, nrows=4, sharex=True, figsize=figure_size, constrained_layout=False, ) # plot the results for idx, ax in enumerate(axes): # extract heads and specific discharge for newton model head = hobj.get_data(totim=times[idx]) head = get_water_table(head, bot) # extract heads and specific discharge for newton model head1 = hobj1.get_data(totim=times[idx]) head1 = get_water_table(head1, bot) # calculate mean error diff = np.abs(head - head1) # print("max", diff.max(), np.argmax(diff)) me = diff.sum() / float(ncol * nrow) me_text = "Mean absolute water-table error {:.3f} feet".format(me) ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, extent=extents, line={"row": 1}) mm.plot_bc("CHD", color="cyan") mm.plot_grid(lw=0.5) ax.plot( xnode, head[0, :], lw=0.75, color="black", label="Newton-Raphson", ) ax.plot( xnode, head1[0, :], lw=0, marker="o", ms=4, mfc="none", mec="blue", label="Rewetting", ) if idx == 0: ax.plot( -1000, -1000, lw=0, marker="s", ms=4, mec="0.5", mfc="none", label="Model cell", ) ax.plot( -1000, -1000, lw=0, marker="s", ms=4, mec="0.5", mfc="cyan", label="Constant head", ) fs.graph_legend( ax, loc="upper right", ncol=2, frameon=True, facecolor="white", edgecolor="none", ) letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, ax=ax) fs.add_text(ax, text=me_text, x=1, y=1.01, ha="right", bold=False) fs.remove_edge_ticks(ax) # set fake y-axis label ax.set_ylabel(" ") # set fake x-axis label ax.set_xlabel(" ") ax = fig.add_subplot(1, 1, 1, frameon=False) ax.tick_params(labelcolor="none", top="off", bottom="off", left="off", right="off") ax.set_xlim(0, 1) ax.set_xticks([0, 1]) ax.set_xlabel("x-coordinate, in feet") ax.set_ylim(0, 1) ax.set_yticks([0, 1]) ax.set_ylabel("Water-table elevation above arbitrary datum, in meters") fs.remove_edge_ticks(ax) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_grid(silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[0] # # load the model # sim = flopy.mf6.MFSimulation.load(sim_name=name, sim_ws=sim_ws) # gwf = sim.get_model(name) xrange = (0, 1) chds = (5, 10, 12) fig, axes = plt.subplots(nrows=1, ncols=3, sharey=True, figsize=(5.1, 4.0)) for idx, ax in enumerate(axes): ax.set_xlim(xrange) ax.set_ylim(edges[-1][0], 0) for edge in edges: ax.plot(xrange, edge, lw=0.5, color="black") ax.tick_params( axis="x", which="both", bottom=False, top=False, labelbottom=False ) ax.tick_params(axis="y", which="both", right=False, labelright=False) ax = axes[0] ax.fill_between( xrange, edges[0], y2=edges[1], color="green", lw=0, label="Upper aquifer", ) label = "" for k in (1, 2, 3): label = set_label(label, text="Confining unit") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="brown", lw=0, label=label ) label = "" for k in (7, 8, 9): label = set_label(label, text="Thick aquitard") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="tan", lw=0, label=label ) # middle aquifer midz = 825.0 / 3.8081 midz = [edges[4], edges[7], edges[10], (midz, midz)] ax.fill_between( xrange, midz[0], y2=midz[1], color="cyan", lw=0, label="Middle aquifer" ) ax.fill_between(xrange, midz[2], y2=midz[3], color="cyan", lw=0) # lower aquifer ax.fill_between( xrange, midz[-1], y2=edges[-1], color="blue", lw=0, label="Lower aquifer", ) fs.graph_legend(ax, loc="lower right", frameon=True, framealpha=1) fs.heading(ax=ax, letter="A", heading="Hydrostratigraphy") fs.remove_edge_ticks(ax) ax.set_ylabel("Depth below land surface, in meters") # csub interbeds ax = axes[1] nodelay = (1, 2, 3, 6, 7, 8, 9) label = "" for k in nodelay: label = set_label(label, text="No-delay") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="0.5", lw=0, label=label ) comb = [4, 11, 13] label = "" for k in comb: label = set_label(label, text="No-delay\nand delay") ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="brown", lw=0, label=label ) for k in chds: ax.fill_between( xrange, edges[k], y2=edges[k + 1], color="white", lw=0.75, zorder=100, ) leg = fs.graph_legend(ax, loc="lower right", frameon=True, framealpha=1) leg.set_zorder(100) fs.heading(ax=ax, letter="B", heading="Interbed types") fs.remove_edge_ticks(ax) # boundary conditions ax = axes[2] constant_heads(ax) for k in llabels: print_label(ax, edges, k) fs.graph_legend(ax, loc="lower left") fs.heading(ax=ax, letter="C", heading="Boundary conditions") fs.remove_edge_ticks(ax) fig.tight_layout(pad=0.5) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_local_grid(silent=True): if silent: verbosity = 0 else: verbosity = 1 name = list(parameters.keys())[1] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load( sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity ) gwf = sim.get_model(sim_name) i, j = maw_loc dx, dy = delr[j], delc[i] px = ( 50.0 - 0.5 * dx, 50.0 + 0.5 * dx, ) py = ( 0.0 + dy, 0.0 + dy, ) # get regional heads for constant head boundaries h = gwf.output.head().get_data() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(6.3, 4.1), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 8))] for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (8, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents, layer=0) mm.plot_bc("CHD", color="cyan", plotAll=True) mm.plot_grid(lw=0.25, color="0.5") cv = mm.contour_array( h, levels=np.arange(4.0, 5.0, 0.005), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.3f") ax.fill_between( px, py, y2=0, ec="none", fc="red", lw=0, zorder=200, step="post" ) fs.add_annotation( ax, text="Well location", xy=(50.0, 0.0), xytext=(55, 5), bold=False, italic=False, ha="left", fontsize=7, arrowprops=arrow_props, ) fs.remove_edge_ticks(ax) ax.set_xticks([0, 25, 50, 75, 100]) ax.set_xlabel("x-coordinate, in feet") ax.set_yticks([0, 25, 50]) ax.set_ylabel("y-coordinate, in feet") # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="0.5", markeredgewidth=0.25, label="Constant head", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="red", mec="0.5", markeredgewidth=0.25, label="Multi-aquifer well", ) ax.plot( -10000, -10000, lw=0.5, color="black", label="Water-table contour, $ft$", ) fs.graph_legend(ax, loc="lower center", ncol=3) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-local-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_grid(gwf, silent=True): sim_ws = os.path.join(ws, sim_name) # load the observations fpth = os.path.join(ws, sim_name, "{}.lak.obs.csv".format(sim_name)) lak_results = np.genfromtxt(fpth, delimiter=",", names=True) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") kstpkper = hobj.get_kstpkper() head = hobj.get_data(kstpkper=kstpkper[0]) spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0]) # add lake stage to heads head[head == 1e30] = lak_results["STAGE"][-1] # observation locations xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1] p1 = (xcenters[3], ycenters[3]) p2 = (xcenters[13], ycenters[13]) fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(4, 6.9), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 5))] axes.append(fig.add_subplot(nrows, ncols, (6, 8), sharex=axes[0])) for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) if idx == 0: ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (9, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) mm.plot_bc("CHD", color="cyan") mm.plot_inactive(color_noflow="#5DBB63") mm.plot_grid(lw=0.5, color="black") cv = mm.contour_array( head, levels=np.arange(140, 160, 2), linewidths=0.75, linestyles="-", colors="blue", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_specific_discharge(spdis, normalize=True, color="0.75") ax.plot(p1[0], p1[1], marker="o", mfc="red", mec="black", ms=4) ax.plot(p2[0], p2[1], marker="o", mfc="red", mec="black", ms=4) ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.heading(ax, heading="Map view", idx=0) fs.add_text( ax, "A", x=p1[0] + 150, y=p1[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.add_text( ax, "B", x=p2[0] + 150, y=p2[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.remove_edge_ticks(ax) ax = axes[1] xs = flopy.plot.PlotCrossSection(gwf, ax=ax, line={"row": 8}) xs.plot_array(np.ones(shape3d), head=head, cmap="jet") xs.plot_bc("CHD", color="cyan", head=head) xs.plot_ibound(color_noflow="#5DBB63", head=head) xs.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") ax.set_ylim(67, 160) ax.set_ylabel("Elevation, in feet") fs.heading(ax, heading="Cross-section view", idx=1) fs.remove_edge_ticks(ax) # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="#5DBB63", mec="black", markeredgewidth=0.5, label="Lake boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="black", markeredgewidth=0.5, label="Constant-head boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="blue", mec="black", markeredgewidth=0.5, label="Water table", ) ax.plot( -10000, -10000, lw=0, marker="o", ms=4, mfc="red", mec="black", markeredgewidth=0.5, label="Observation well", ) ax.plot( -10000, -10000, lw=0.75, ls="-", color="blue", label=r"Head contour, $ft$", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) fs.graph_legend(ax, loc="lower center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_calibration(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = list(parameters.keys())[1] pth = os.path.join(ws, name, "{}.csub.obs.csv".format(name)) df_sim = get_sim_dataframe(pth) df_sim.rename({"TOTAL": "simulated"}, inplace=True, axis=1) pth = os.path.join("..", "data", sim_name, "boundary_heads.csv") df_obs_heads, col_list = process_sim_csv(pth) ccolors = ( "black", "tan", "cyan", "brown", "blue", "violet", ) xf0 = datetime.datetime(1907, 1, 1, 0, 0, 0) xf1 = datetime.datetime(2007, 1, 1, 0, 0, 0) xf0s = datetime.datetime(1990, 1, 1, 0, 0, 0) xf1s = datetime.datetime(2007, 1, 1, 0, 0, 0) xc0 = datetime.datetime(1992, 10, 1, 0, 0, 0) xc1 = datetime.datetime(2006, 9, 4, 0, 0, 0) dx = xc1 - xc0 xca = xc0 + dx / 2 # get observation data df = get_obs_dataframe(file_name="008N010W01Q005S_obs.csv") ix0 = df.index.get_loc("2006-09-04 00:00:00") offset = df_sim["simulated"].values[-1] - df.observed.values[ix0] df.observed += offset # -- subplot a ----------------------------------------------------------- # build box for subplot B o = datetime.timedelta(31) ix = (xf0s, xf0s, xf1s - o, xf1s - o, xf0s) iy = (1.15, 1.45, 1.45, 1.15, 1.15) # -- subplot a ----------------------------------------------------------- # -- subplot c ----------------------------------------------------------- # get observations df_pc = get_obs_dataframe() # get index for start of calibration period for subplot c ix0 = df_sim.index.get_loc("1992-10-01 12:00:00") # get initial simulated compaction cstart = df_sim.simulated[ix0] # cut off initial portion of simulated compaction df_sim_pc = df_sim[ix0:].copy() # reset initial compaction to 0. df_sim_pc.simulated -= cstart # reset simulated so maximum compaction is the same offset = df_pc.observed.values.max() - df_sim_pc.simulated.values[-1] df_sim.simulated += offset # interpolate subsidence observations to the simulation index for subplot c df_iobs_pc = dataframe_interp(df_pc, df_sim_pc.index) # truncate head to start of observations head_pc = dataframe_interp(df_obs_heads, df_sim_pc.index) # calculate geostatic stress gs = sgm * (0.0 - head_pc.CHD_L01.values) + sgs * ( head_pc.CHD_L01.values - botm[-1] ) # calculate hydrostatic stress for subplot c u = head_pc.CHD_L13.values - botm[-1] # calculate effective stress es_obs = gs - u # set up indices for date text for plot c locs = ["{:04d}-10-01 12:00:00".format(yr) for yr in range(1992, 2006)] locs += ["{:04d}-04-01 12:00:00".format(yr) for yr in range(1993, 2007)] locs += ["2006-09-04 12:00:00"] ixs = [head_pc.index.get_loc(loc) for loc in locs] # -- subplot c ----------------------------------------------------------- ctext = "Calibration period\n{} to {}".format( xc0.strftime("%B %d, %Y"), xc1.strftime("%B %d, %Y") ) fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(6.8, 6.8)) # -- plot a -------------------------------------------------------------- ax = axes.flat[0] ax.set_xlim(xf0, xf1) ax.plot([xf0, xf1], [0, 0], lw=0.5, color="0.5") ax.plot( [ xf0, ], [ -10, ], marker=".", ms=1, lw=0, color="red", label="Holly site (8N/10W-1Q)", ) for idx, key in enumerate(pcomp): if key == "TOTAL": key = "simulated" color = ccolors[idx] label = clabels[idx] ax.plot( df_sim.index.values, df_sim[key].values, color=color, label=label, lw=0.75, ) ax.plot(ix, iy, lw=1.0, color="red", zorder=200) fs.add_text(ax=ax, text="B", x=xf0s, y=1.14, transform=False) ax.set_ylim(1.5, -0.1) ax.xaxis.set_ticks(df_xticks) ax.xaxis.set_major_formatter(mpl.dates.DateFormatter("%m/%d/%Y")) ax.set_ylabel("Compaction, in {}".format(length_units)) ax.set_xlabel("Year") fs.graph_legend(ax=ax, frameon=False) fs.heading(ax, letter="A") fs.remove_edge_ticks(ax=ax) # -- plot b -------------------------------------------------------------- ax = axes.flat[1] ax.set_xlim(xf0s, xf1s) ax.set_ylim(1.45, 1.15) ax.plot( df.index.values, df["observed"].values, marker=".", ms=1, lw=0, color="red", ) ax.plot( df_sim.index.values, df_sim["simulated"].values, color="black", label=label, lw=0.75, ) # plot lines for calibration ax.plot([xc0, xc0], [1.45, 1.15], color="black", lw=0.5, ls=":") ax.plot([xc1, xc1], [1.45, 1.15], color="black", lw=0.5, ls=":") fs.add_annotation( ax=ax, text=ctext, italic=False, bold=False, xy=(xc0 - o, 1.2), xytext=(xca, 1.2), ha="center", va="center", arrowprops=dict(arrowstyle="-|>", fc="black", lw=0.5), color="none", bbox=dict(boxstyle="square,pad=-0.07", fc="none", ec="none"), ) fs.add_annotation( ax=ax, text=ctext, italic=False, bold=False, xy=(xc1 + o, 1.2), xytext=(xca, 1.2), ha="center", va="center", arrowprops=dict(arrowstyle="-|>", fc="black", lw=0.5), bbox=dict(boxstyle="square,pad=-0.07", fc="none", ec="none"), ) ax.yaxis.set_ticks(np.linspace(1.15, 1.45, 7)) ax.xaxis.set_ticks(df_xticks1) ax.xaxis.set_major_locator(mpl.dates.YearLocator()) ax.xaxis.set_minor_locator(mpl.dates.YearLocator(month=6, day=15)) ax.xaxis.set_major_formatter(mpl.ticker.NullFormatter()) ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter("%Y")) ax.tick_params(axis="x", which="minor", length=0) ax.set_ylabel("Compaction, in {}".format(length_units)) ax.set_xlabel("Year") fs.heading(ax, letter="B") fs.remove_edge_ticks(ax=ax) # -- plot c -------------------------------------------------------------- ax = axes.flat[2] ax.set_xlim(-0.01, 0.2) ax.set_ylim(368, 376) ax.plot( df_iobs_pc.observed.values, es_obs, marker=".", ms=1, color="red", lw=0, label="Holly site (8N/10W-1Q)", ) ax.plot( df_sim_pc.simulated.values, df_sim_pc.ES14.values, color="black", lw=0.75, label="Simulated", ) for idx, ixc in enumerate(ixs): text = "{}".format(df_iobs_pc.index[ixc].strftime("%m/%d/%Y")) if df_iobs_pc.index[ixc].month == 4: dxc = -0.001 dyc = -1 elif df_iobs_pc.index[ixc].month == 9: dxc = 0.002 dyc = 0.75 else: dxc = 0.001 dyc = 1 xc = df_iobs_pc.observed[ixc] yc = es_obs[ixc] fs.add_annotation( ax=ax, text=text, italic=False, bold=False, xy=(xc, yc), xytext=(xc + dxc, yc + dyc), ha="center", va="center", fontsize=7, arrowprops=dict(arrowstyle="-", color="red", fc="red", lw=0.5), bbox=dict(boxstyle="square,pad=-0.15", fc="none", ec="none"), ) xtext = "Total compaction since {}, in {}".format( df_sim_pc.index[0].strftime("%B %d, %Y"), length_units ) ytext = ( "Effective stress at the bottom of\nthe lower aquifer, in " + "{} of water".format(length_units) ) ax.set_xlabel(xtext) ax.set_ylabel(ytext) fs.heading(ax, letter="C") fs.remove_edge_ticks(ax=ax) fs.remove_edge_ticks(ax) # finalize figure fig.tight_layout(pad=0.01) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-03{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_grid(gwf, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) bot = gwf.dis.botm.array fig, axes = create_figure() ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) bot_coll = mm.plot_array(bot, vmin=bmin, vmax=bmax) mm.plot_bc("CHD", color="cyan") cv = mm.contour_array( bot, levels=blevels, linewidths=0.5, linestyles=":", colors=bcolor, ) plt.clabel(cv, fmt="%1.0f") ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.remove_edge_ticks(ax) # legend ax = axes[1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0.5, ls=":", color=bcolor, label="Bottom elevation contour, m", ) fs.graph_legend(ax, loc="center", ncol=2) cax = plt.axes([0.275, 0.125, 0.45, 0.025]) cbar = plt.colorbar( bot_coll, shrink=0.8, orientation="horizontal", cax=cax, ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Bottom Elevation, $m$") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_head_results(gwf, silent=True): sim_ws = os.path.join(ws, sim_name) # create MODFLOW 6 head object hobj = gwf.output.head() # create MODFLOW 6 cell-by-cell budget object cobj = gwf.output.budget() kstpkper = hobj.get_kstpkper() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure(figsize=figure_size, constrained_layout=False) gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5) plt.axis("off") axes = [fig.add_subplot(gs[:6, :5])] axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0])) for ax in axes: ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(gs[6:, :])) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) # extract heads and specific discharge for first stress period head = hobj.get_data(kstpkper=kstpkper[0]) qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge( cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0])[0], gwf, ) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values) cv = mm.contour_array( head, levels=np.arange(900, 1100, 10), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_vector(qx, qy, normalize=True, color="0.75") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.heading(ax, heading="Steady-state", idx=0) fs.remove_edge_ticks(ax) # extract heads and specific discharge for second stress period head = hobj.get_data(kstpkper=kstpkper[1]) qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge( cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[1])[0], gwf, ) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values) cv = mm.contour_array( head, levels=np.arange(900, 1100, 10), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_vector(qx, qy, normalize=True, color="0.75") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") fs.heading(ax, heading="Pumping", idx=1) fs.remove_edge_ticks(ax) # legend ax = axes[-1] cbar = plt.colorbar( head_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $ft$") ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) ax.plot(-10000, -10000, lw=0.5, color="black", label=r"Head contour, $ft$") fs.graph_legend(ax, loc="upper center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_results(idx, sim, silent=True): verbose = not silent if config.plotModel: fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[idx] sim_ws = os.path.join(ws, name) gwf = sim.get_model(sim_name) bot = gwf.dis.botm.array if idx == 0: plot_grid(gwf, silent=silent) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") # extract heads and specific discharge head = hobj.get_data(totim=1.0) imask = (head > -1e30) & (head <= bot) head[imask] = -1e30 # botm[imask] spdis = cobj.get_data(text="DATA-SPDIS", totim=1.0) # Create figure for simulation fig, axes = create_figure() ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) if bot.max() < 20: cv = mm.contour_array( bot, levels=blevels, linewidths=0.5, linestyles=":", colors=bcolor, zorder=9, ) plt.clabel(cv, fmt="%1.0f", zorder=9) h_coll = mm.plot_array(head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10) cv = mm.contour_array( head, masked_values=masked_values, levels=vlevels, linewidths=0.5, linestyles="-", colors=vcolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) mm.plot_specific_discharge(spdis, normalize=True, color="0.75", zorder=11) ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.remove_edge_ticks(ax) # create legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) if bot.max() < 20: ax.plot( -10000, -10000, lw=0.5, ls=":", color=bcolor, label="Bottom elevation contour, m", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color=vcolor, label="Head contour, m", ) fs.graph_legend(ax, loc="center", ncol=2) cax = plt.axes([0.275, 0.125, 0.45, 0.025]) cbar = plt.colorbar(h_coll, shrink=0.8, orientation="horizontal", cax=cax) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $m$", fontsize=9) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{:02d}{}".format(sim_name, idx + 1, config.figure_ext), ) fig.savefig(fpth)
def plot_results(silent=True): if config.plotModel: verbose = not silent if silent: verbosity_level = 0 else: verbosity_level = 1 fs = USGSFigure(figure_type="map", verbose=verbose) sim_ws = os.path.join(ws, sim_name) sim = flopy.mf6.MFSimulation.load(sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level) gwf = sim.get_model(sim_name) # load the capture fraction data fpth = os.path.join(sim_ws, "capture.npz") capture = np.load(fpth)["capture"] # plot grid fig = plt.figure(figsize=(4, 3.75), constrained_layout=True) gs = mpl.gridspec.GridSpec( 2, 2, figure=fig, width_ratios=(4, 1), height_ratios=(1, 6), ) ax = fig.add_subplot(gs[:, 0]) ax.set_aspect("equal") # ax = fig.add_subplot(1, 1, 1) # ax.set_aspect("equal") mm = flopy.plot.PlotMapView(model=gwf, ax=ax) cf = mm.plot_array(capture, vmin=0, vmax=1) mm.plot_grid(lw=0.5, color="0.5") mm.plot_bc('WEL') ax.axvline(x=14.5 * delc, lw=1.25, color="cyan") mm.plot_bc('CHD', color="green") mm.plot_ibound() ax.set_ylabel("y-coordinate, in feet") ax.set_xlabel("x-coordinate, in feet") fs.remove_edge_ticks(ax) ax = fig.add_subplot(gs[0, 1]) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) cbar = plt.colorbar(cf, ax=ax, orientation="horizontal") cbar.ax.set_xlabel("Streamflow capture fraction") ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="Constant head", ) ax.plot( -1000, -1000, color="cyan", lw=1.25, label="River", ) ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) ax.plot( -1000, -1000, "s", ms=5, color="black", mec="black", mew=0.5, label="Inactive cell", ) fs.graph_legend( ax, ncol=1, frameon=False, loc="upper center", ) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(sim_name, config.figure_ext)) fig.savefig(fpth)
def plot_grid(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) name = sim.name gwf = sim.get_model(name) extents = gwf.modelgrid.extent # read simulated heads pth = os.path.join(ws, name, "{}.hds".format(name)) hobj = flopy.utils.HeadFile(pth) h0 = hobj.get_data(kstpkper=(0, 0)) h1 = hobj.get_data(kstpkper=(59, 1)) hsxs0 = h0[0, 8, :] hsxs1 = h1[0, 8, :] # get delr array dx = gwf.dis.delr.array # create x-axis for cross-section hxloc = np.arange(1000, 2000.0 * 15, 2000.0) # set cross-section location y = 2000.0 * 11.5 xsloc = [(extents[0], extents[1]), (y, y)] # well locations w1loc = (9.5 * 2000.0, 11.75 * 2000.0) w2loc = (6.5 * 2000.0, 8.5 * 2000.0) fig = plt.figure(figsize=(6.8, 5), constrained_layout=True) gs = mpl.gridspec.GridSpec(7, 10, figure=fig, wspace=5) plt.axis("off") ax = fig.add_subplot(gs[:, 0:6]) # ax.set_aspect('equal') mm = flopy.plot.PlotMapView(model=gwf, ax=ax, extent=extents) mm.plot_grid(lw=0.5, color="0.5") mm.plot_bc(ftype="WEL", kper=1, plotAll=True) mm.plot_bc(ftype="CHD", color="blue") mm.plot_bc(ftype="RCH", color="green") mm.plot_inactive(color_noflow="0.75") mm.ax.plot(xsloc[0], xsloc[1], color="orange", lw=1.5) # contour steady state heads cl = mm.contour_array( h0, masked_values=[1.0e30], levels=np.arange(115, 200, 5), colors="black", linestyles="dotted", linewidths=0.75, ) ax.clabel(cl, fmt="%3i", inline_spacing=0.1) # well text fs.add_annotation( ax=ax, text="Well 1, layer 2", bold=False, italic=False, xy=w1loc, xytext=(w1loc[0] - 3200, w1loc[1] + 1500), ha="right", va="center", zorder=100, arrowprops=arrow_props, ) fs.add_annotation( ax=ax, text="Well 2, layer 4", bold=False, italic=False, xy=w2loc, xytext=(w2loc[0] + 3000, w2loc[1]), ha="left", va="center", zorder=100, arrowprops=arrow_props, ) ax.set_ylabel("y-coordinate, in meters") ax.set_xlabel("x-coordinate, in meters") fs.heading(ax, letter="A", heading="Map view") fs.remove_edge_ticks(ax) ax = fig.add_subplot(gs[0:5, 6:]) mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={"row": 8}) mm.plot_grid(lw=0.5, color="0.5") # items for legend mm.ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="Recharge", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="blue", mec="black", mew=0.5, label="Constant head", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="0.75", mec="black", mew=0.5, label="Inactive", ) mm.ax.plot( [-1000, -1001], [-1000, -1000], color="orange", lw=1.5, label="Cross-section line", ) # aquifer coloring ax.fill_between([0, dx.sum()], y1=150, y2=-100, color="cyan", alpha=0.5) ax.fill_between([0, dx.sum()], y1=-100, y2=-150, color="#D2B48C", alpha=0.5) ax.fill_between([0, dx.sum()], y1=-150, y2=-350, color="#00BFFF", alpha=0.5) # well coloring ax.fill_between([dx.cumsum()[8], dx.cumsum()[9]], y1=50, y2=-100, color="red", lw=0) # labels fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-97, text="Upper aquifer", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-147, text="Confining unit", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-347, text="Lower aquifer", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=53, text="Layer 1", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-97, text="Layer 2", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-147, text="Layer 3", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-347, text="Layer 4", va="bottom", ha="right", fontsize=9, ) ax.plot( hxloc, hsxs0, lw=0.75, color="black", ls="dotted", label="Steady-state\nwater level", ) ax.plot( hxloc, hsxs1, lw=0.75, color="black", ls="dashed", label="Water-level at the end\nof stress-period 2", ) ax.set_ylabel("Elevation, in meters") ax.set_xlabel("x-coordinate along model row 9, in meters") fs.graph_legend( mm.ax, ncol=2, bbox_to_anchor=(0.5, -0.6), borderaxespad=0, frameon=False, loc="lower center", ) fs.heading(ax, letter="B", heading="Cross-section view") fs.remove_edge_ticks(ax) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_head_based(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name # get csub observations ws = sim.simulation_data.mfpath.get_sim_path() s = flopy.mf6.MFSimulation().load(sim_ws=ws, verbosity_level=0) gwf = s.get_model(name) cobs = gwf.csub.output.obs().data # calculate the compaction analytically ac = [] nz = 100 thick = parameters[name]["bed_thickness"][0] kv = parameters[name]["kv"][0] dhalf = thick * 0.5 az = np.linspace(-dhalf, dhalf, num=nz) dz = az[1] - az[0] for tt in cobs["totim"]: c = 0.0 for jdx, zz in enumerate(az): f = 1.0 if jdx == 0 or jdx == nz - 1: f = 0.5 h = analytical_solution(zz, tt, ssk=skv, vk=kv, n=200, dh=1.0) c += h * skv * f * dz ac.append(c) ac = np.array(ac) # calculate normalized simulation time tpct = cobs["totim"] * 100 / tau0 # plot the results fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(1, 2, figure=fig) idx = 0 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * ac / skv, marker=".", lw=0, ms=3, color="red", label="Analytical", ) ax.plot( tpct, 100 * cobs["TCOMP"] / skv, label="Simulated", color="black", lw=1, zorder=100, ) leg = fs.graph_legend(ax, loc="lower right") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel("Compaction, in percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 100) fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) idx += 1 ax = fig.add_subplot(gs[idx]) ax.plot(tpct, 100 * (ac - cobs["TCOMP"]) / skv, lw=1, ls=":", color="black") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 2.2, 0.2)) ax.set_xlabel("Percent of time constant") ax.set_ylabel( "Analytical minus simulated subsidence,\nin percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 2) fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_stresses(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name cd = get_csub_observations(sim) tmax = cd["time"][-1] fig, axes = plt.subplots( ncols=1, nrows=4, figsize=figure_size, sharex=True, constrained_layout=True, ) idx = 0 ax = axes[idx] ax.set_xlim(0, tmax) ax.set_ylim(110, 150) ax.plot( cd["time"], cd["PC1"], color="blue", lw=1, label="Preconsolidation stress", ) ax.plot(cd["time"], cd["ES1"], color="red", lw=1, label="Effective stress") fs.heading(ax, letter="A", heading="Model layer 1, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(185, 205) ax.plot(cd["time"], cd["GS1"], color="black", lw=1) fs.heading(ax, letter="B", heading="Model layer 1, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(270, 310) ax.plot(cd["time"], cd["PC2"], color="blue", lw=1) ax.plot(cd["time"], cd["ES2"], color="red", lw=1) fs.heading(ax, letter="C", heading="Model layer 2, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(495, 515) ax.plot( [-100, -50], [-100, -100], color="blue", lw=1, label="Preconsolidation stress", ) ax.plot([-100, -50], [-100, -100], color="red", lw=1, label="Effective stress") ax.plot(cd["time"], cd["GS2"], color="black", lw=1, label="Geostatic stress") fs.graph_legend(ax, ncol=3, loc="upper center") fs.heading(ax, letter="D", heading="Model layer 2, row 9, column 10") fs.remove_edge_ticks(ax) ax.set_xlabel("Simulation time, in years") ax.set_ylabel(" ") ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[]) ax.set_ylabel("Stress, in meters of water") # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_head_comparison(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name ndcells = parameters[name]["ndelaycells"] thicknesses = parameters[name]["bed_thickness"] # get the subdirectory names hb_dirs, es_dirs = get_subdirs(sim) # setup the figure fig = plt.figure(figsize=figure_size) fig.subplots_adjust(left=0.06, right=0.95, top=0.95, bottom=0.15, wspace=0.1) gs = mpl.gridspec.GridSpec(1, 6, figure=fig) z = np.linspace(0, 1, ndcells) yticks = np.arange(0, 1.1, 0.1) # set color cmap = plt.get_cmap("viridis") cNorm = mpl.colors.Normalize(vmin=0, vmax=6) scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap) # percentages to evaluate pct_vals = ( 1, 5, 10, 50, 100, ) axes = [] for idx in range(6): ax = fig.add_subplot(gs[idx]) ax.set_ylim(1, 0) ax.set_xlim(-5, 5) if idx < 5: fs.heading(ax, letter=chr(ord("A") + idx)) ax.set_yticks(yticks) fs.remove_edge_ticks(ax) text = r"$\frac{t}{\tau_0}$ = " + "{}".format( pct_vals[idx] / 100.0) ax.text( 0.25, 0.01, text, ha="center", va="bottom", transform=ax.transAxes, fontsize=8, ) else: ax.set_xticks([]) ax.set_yticks([]) if idx == 0: ax.set_ylabel("Interbed position, relative to interbed thickness") else: if idx == 2: text = ( "Difference in head-based and effective stress-based" + "\ninterbed heads, in percent of head-based interbed heads" ) ax.set_xlabel(text) ax.set_yticklabels([]) axes.append(ax) for idx, (hb_dir, es_dir) in enumerate(zip(hb_dirs, es_dirs)): sim_ws = os.path.join(ws, name, hb_dir) s = flopy.mf6.MFSimulation().load(sim_ws=sim_ws, verbosity_level=0) g = s.get_model(name) hb_obs = g.csub.output.obs().data hb_arr = fill_heads(hb_obs, ndcells) ws0 = os.path.join(ws, name, es_dir) s0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0) g0 = s0.get_model(name) es_obs = g0.csub.output.obs().data es_arr = fill_heads(es_obs, ndcells) # # pth = os.path.join(ws, name, hb_dir, "{}.csub.obs.csv".format(name)) # hb_obs = np.genfromtxt(pth, names=True, delimiter=",") # hb_arr = fill_heads(hb_obs, ndcells) # # pth = os.path.join(ws, name, es_dir, "{}.csub.obs.csv".format(name)) # es_obs = np.genfromtxt(pth, names=True, delimiter=",") # es_arr = fill_heads(es_obs, ndcells) # calculate normalized simulation time tpct = hb_obs["totim"] * 100 / tau0 # calculate location closest to 1, 5, 10, 50, and 100 percent of time constant locs = {} for i in pct_vals: for jdx, t in enumerate(tpct): if t <= i: locs[i] = jdx for jdx, (key, ivalue) in enumerate(locs.items()): # add data to the subplot ax = axes[jdx] if idx == 0: color = "black" else: color = scalarMap.to_rgba(idx - 1) hhb = hb_arr[ivalue, :] hes = es_arr[ivalue, :] v = 100.0 * (hhb - hes) / hhb ax.plot(v, z, lw=0.75, color=color) # legend ax = axes[-1] ax.set_ylim(1, 0) ax.set_xlim(-5, 5) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) for ic, b in enumerate(thicknesses): if ic == 0: color = "black" else: color = scalarMap.to_rgba(ic - 1) label = "Thickness = {:>3d} m".format(int(b)) ax.plot([-1, -1], [-1, -1], lw=0.75, color=color, label=label) leg = fs.graph_legend(ax, loc="center", bbox_to_anchor=(0.64, 0.5)) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-02{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_results(sim, silent=True): if config.plotModel: fs = USGSFigure(figure_type="map", verbose=False) sim_ws = os.path.join(ws, sim_name) gwf = sim.get_model(sim_name) # plot the grid fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(10, 1, figure=fig) idx = 0 ax = fig.add_subplot(gs[0:3]) extent = (0, xmax, 0, 100) ax.set_ylim(0, 100) mm = flopy.plot.PlotMapView(model=gwf, ax=ax, extent=extent) mm.plot_grid(color='0.5', lw=0.5, zorder=100) ax.set_ylabel('y-coordinate,\nin meters') x, y = gwf.modelgrid.xcellcenters[ 0, locw201], gwf.modelgrid.ycellcenters[0, 0] ax.plot(x, y, marker='o', ms=4, zorder=100, mew=0.5, mec='black') ax.annotate('Well S-201', xy=(x + 5, y), xytext=(x + 75, y), ha='left', va='center', zorder=100, arrowprops=dict(facecolor='black', shrink=0.05, headwidth=5, width=1.5)) fs.heading(ax, letter='A', heading='Map view') fs.remove_edge_ticks(ax) ax.axes.get_xaxis().set_ticks([]) idx += 1 ax = fig.add_subplot(gs[3:]) extent = (0, xmax, botm[-1], 0) mc = flopy.plot.PlotCrossSection(model=gwf, line={'Row': 0}, ax=ax, extent=extent) ax.fill_between([0, delr.sum()], y1=top, y2=botm[0], color='cyan', alpha=0.5) ax.fill_between([0, delr.sum()], y1=botm[0], y2=botm[1], color='#D2B48C', alpha=0.5) ax.fill_between([0, delr.sum()], y1=botm[1], y2=botm[2], color='#00BFFF', alpha=0.5) mc.plot_grid(color='0.5', lw=0.5, zorder=100) ax.plot([0, delr.sum()], [-35 / 3.28081, -35 / 3.28081], lw=0.75, color='black', ls='dashed') ax.text(delr.sum() / 2, -10, 'static water-level', va='bottom', ha='center', size=9) ax.set_ylabel('Elevation, in meters') ax.set_xlabel('x-coordinate, in meters') fs.heading(ax, letter='B', heading='Cross-section view') fs.remove_edge_ticks(ax) fig.align_ylabels() plt.tight_layout(pad=1, h_pad=0.001, rect=(.005, -0.02, 0.99, 0.99)) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) fig.savefig(fpth) # get the simulated heads sim_obs = gwf.obs.output.obs().data h0 = sim_obs["W3_1_1"][0] sim_obs["W3_1_1"] -= h0 sim_date = [ dstart + datetime.timedelta(seconds=x) for x in sim_obs["totim"] ] # get the observed head pth = os.path.join("..", "data", sim_name, "s201_gw_2sec.csv") dtype = [("date", object), ("dz_m", float)] obs_head = np.genfromtxt(pth, names=True, delimiter=",", dtype=dtype) obs_date = [] for s in obs_head["date"]: obs_date.append( datetime.datetime.strptime(s.decode("utf-8"), '%m-%d-%Y %H:%M:%S.%f')) t0, t1 = obs_date[0], obs_date[-1] # plot the results fs = USGSFigure(figure_type="graph", verbose=False) fig = plt.figure(figsize=(6.8, 4.)) gs = mpl.gridspec.GridSpec(2, 1, figure=fig) axe = fig.add_subplot(gs[-1]) idx = 0 ax = fig.add_subplot(gs[idx], sharex=axe) ax.set_ylim(0, 3.25) ax.set_yticks(np.arange(0, 3.5, 0.5)) ax.fill_between(date_list, csv_load["load"], y2=0, color='cyan', lw=0.5, alpha=0.5) ax.set_ylabel('Load, in meters\nof water') plt.setp(ax.get_xticklabels(), visible=False) fs.heading(ax, letter='A') fs.remove_edge_ticks(ax) ax = axe ax.plot(sim_date, sim_obs["W3_1_1"], color='black', lw=0.75, label='Simulated') ax.plot(obs_date, obs_head["dz_m"], color='red', lw=0, ms=4, marker='.', label='Offset S-201') ax.axhline(0, lw=0.5, color='0.5') ax.set_ylabel('Water level fluctuation,\nin meters') fs.heading(ax, letter='B') leg = fs.graph_legend(ax, loc='upper right', ncol=1) ax.set_xlabel('Time') ax.set_ylim(-0.004, 0.008) axe.set_xlim(t0, t1) fs.remove_edge_ticks(ax) fig.align_ylabels() plt.tight_layout(pad=1, h_pad=0.001, rect=(.005, -0.02, 0.99, 0.99)) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(sim_name, config.figure_ext)) fig.savefig(fpth)