def plot_head_results(gwf, silent=True): sim_ws = os.path.join(ws, 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") 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]) spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0]) 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_specific_discharge(spdis, 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]) spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[1]) 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) # mm.plot_bc("GHB", color="purple") # mm.plot_bc("WEL", color="red", kper=1) 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_specific_discharge(spdis, 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(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_concentration(sim): # Get the concentration output gwt_outer = sim.get_model(gwtname_out) gwt = sim.get_model(gwtname_inn) ucnobj_mf6 = gwt.output.concentration() conc_mf6 = ucnobj_mf6.get_alldata() ucnobj_mf6_outer = gwt_outer.output.concentration() conc_mf6_outer = ucnobj_mf6_outer.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] xc, yc = gwt.modelgrid.xycenters # Plot init. concentration (lay=3) fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(2, 2, 1, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) cs = mm.contour_array(sconc[2], levels=np.arange(20, 200, 20)) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.clabel(cs, fmt=r"%3d") # Plot the wells as well for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Layer 3 Initial Concentration" fs.heading(letter='A', heading=title) ax = fig.add_subplot(2, 2, 2, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) c_500days = conc_mf6_outer[1] c_500days[:, 8:53, 6:34] = conc_mf6[1] # Concentration @ 500 days cs = mm.contour_array(c_500days[2], levels=np.arange(10, 200, 10)) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.clabel(cs, fmt=r"%3d") for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Layer 3 Time = 500 days" fs.heading(letter='B', heading=title) ax = fig.add_subplot(2, 2, 3, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) c_750days = conc_mf6_outer[2] c_750days[:, 8:53, 6:34] = conc_mf6[2] # Concentration @ 750 days cs = mm.contour_array(c_750days[2], levels=np.arange(10, 200, 10)) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.clabel(cs, fmt=r"%3d") for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Layer 3 Time = 750 days" fs.heading(letter='C', heading=title) ax = fig.add_subplot(2, 2, 4, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) c_1000days = conc_mf6_outer[3] c_1000days[:, 8:53, 6:34] = conc_mf6[3] # Concentration @ 1000 days cs = mm.contour_array(c_1000days[2], levels=np.arange(10, 200, 10)) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.clabel(cs, fmt=r"%3d") for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Layer 3 Time = 1000 days" fs.heading(letter='D', heading=title) fpath = os.path.join("..", "figures", "ex-gwtgwt-p10-concentration.png") fig.savefig(fpath) return
def plot_lak_results(gwf, silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations fpth = os.path.join(ws, sim_name, "{}.lak.obs.csv".format(sim_name)) lak_results = np.genfromtxt(fpth, delimiter=",", names=True) fpth = os.path.join(ws, sim_name, "{}.gwf.obs.csv".format(sim_name)) gwf_results = np.genfromtxt(fpth, delimiter=",", names=True) dtype = [ ("time", float), ("LAKE1", float), ("LAKE2", float), ("A", float), ("B", float), ("C", float), ] results = np.zeros((lak_results.shape[0] + 1), dtype=dtype) results["time"][1:] = lak_results["time"] results["LAKE1"][0] = lak_strt results["LAKE1"][1:] = lak_results["LAKE1"] results["LAKE2"][0] = lak_strt results["LAKE2"][1:] = lak_results["LAKE2"] results["A"][0] = strt results["A"][1:] = gwf_results["A"] results["B"][0] = strt results["B"][1:] = gwf_results["B"] results["C"][0] = strt results["C"][1:] = gwf_results["C"] # create the figure fig, axes = plt.subplots( ncols=1, nrows=2, sharex=True, figsize=(6.3, 4.3), constrained_layout=True, ) ax = axes[0] ax.set_xlim(0, 1500) ax.set_ylim(110, 130) ax.plot( results["time"], results["LAKE1"], lw=0.75, ls="--", color="black", label="Lake 1 stage", ) ax.plot( results["time"], results["LAKE2"], lw=0.75, ls="-.", color="black", label="Lake 2 stage", ) ax.set_xticks([0, 250, 500, 750, 1000, 1250, 1500]) ax.set_yticks([110, 115, 120, 125, 130]) ax.set_ylabel("Lake stage, in feet") fs.graph_legend(ax, loc="upper right") fs.heading(ax, idx=0) ax = axes[1] ax.set_xlim(0, 1500) ax.set_ylim(110, 160) ax.plot( results["time"], results["A"], lw=0.75, ls="-", color="0.5", label="Point A", ) ax.plot( results["time"], results["B"], lw=0.75, ls="-", color="black", label="Point B", ) ax.plot( results["time"], results["C"], lw=0.75, ls="-.", color="black", label="Point C", ) ax.set_xticks([0, 250, 500, 750, 1000, 1250, 1500]) ax.set_xlabel("Simulation time, in days") ax.set_yticks([110, 120, 130, 140, 150, 160]) ax.set_ylabel("Head, in feet") fs.graph_legend(ax, loc="upper left") fs.heading(ax, idx=1) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_maw_results(silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations name = list(parameters.keys())[0] fpth = os.path.join(ws, name, "{}.maw.obs.csv".format(sim_name)) maw0 = np.genfromtxt(fpth, delimiter=",", names=True) name = list(parameters.keys())[1] fpth = os.path.join(ws, name, "{}.maw.obs.csv".format(sim_name)) maw1 = np.genfromtxt(fpth, delimiter=",", names=True) time = maw0["time"] * 86400.0 tmin = time[0] tmax = time[-1] # create the figure fig, axes = plt.subplots( ncols=1, nrows=2, sharex=True, figsize=figure_size, constrained_layout=True, ) ax = axes[0] ax.set_xlim(tmin, tmax) ax.set_ylim(-1000, 1000) ax.semilogx( time, maw0["Q1"], lw=0.75, ls="-", color="blue", label="Upper aquifer", ) ax.semilogx( time, maw0["Q2"], lw=0.75, ls="-", color="red", label="Lower aquifer", ) ax.axhline(0, lw=0.5, color="0.5") ax.set_ylabel(" ") fs.heading(ax, heading="Non-pumping case", idx=0) fs.graph_legend(ax, loc="upper right", ncol=2) ax = axes[1] ax.set_xlim(tmin, tmax) ax.set_ylim(-500, 2500) ax.semilogx( time, maw1["Q1"], lw=0.75, ls="-", color="blue", label="Upper aquifer", ) ax.semilogx( time, maw1["Q2"], lw=0.75, ls="-", color="red", label="Lower aquifer", ) ax.axhline(0, lw=0.5, color="0.5") ax.set_xlabel(" ") ax.set_ylabel(" ") for axis in (ax.xaxis, ): axis.set_major_formatter(mpl.ticker.ScalarFormatter()) fs.heading(ax, heading="Pumping case", idx=1) # add y-axis label that spans both subplots ax = fig.add_subplot(1, 1, 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.set_xlabel("Simulation time, in seconds") ax.set_ylabel("Discharge rate, in cubic meters per day") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_results(mf6, idx): if config.plotModel: print("Plotting model results...") sim_name = mf6.name fs = USGSFigure(figure_type="graph", verbose=False) # Start by retrieving some output mf6_out_pth = mf6.simulation_data.mfpath.get_sim_path() sfr_parent_bud_file = list(mf6.model_names)[0] + ".sfr.bud" sfr_child_bud_file = list(mf6.model_names)[1] + ".sfr.bud" sfr_parent_out = os.path.join(mf6_out_pth, sfr_parent_bud_file) sfr_child_out = os.path.join(mf6_out_pth, sfr_child_bud_file) modobjp = bf.CellBudgetFile(sfr_parent_out, precision="double") modobjc = bf.CellBudgetFile(sfr_child_out, precision="double") ckstpkper = modobjp.get_kstpkper() qp = [] qc = [] gwswp = [] gwswc = [] toMvrp = [] fromMvrp = [] toMvrc = [] fromMvrc = [] for kstpkper in ckstpkper: datp = modobjp.get_data(kstpkper=kstpkper, text=" FLOW-JA-FACE") datc = modobjc.get_data(kstpkper=kstpkper, text=" FLOW-JA-FACE") qp.append(datp) qc.append(datc) datp = modobjp.get_data(kstpkper=kstpkper, text=" GWF") datc = modobjc.get_data(kstpkper=kstpkper, text=" GWF") gwswp.append(datp[0]) gwswc.append(datc[0]) # No values for some reason? dat_fmp = modobjp.get_data(kstpkper=kstpkper, text=" FROM-MVR") dat_tmp = modobjp.get_data(kstpkper=kstpkper, text=" TO-MVR") toMvrp.append(dat_fmp[0]) fromMvrp.append(dat_tmp[0]) # No values for some reason? dat_fmc = modobjc.get_data(kstpkper=kstpkper, text=" FROM-MVR") dat_tmc = modobjc.get_data(kstpkper=kstpkper, text=" TO-MVR") toMvrc.append(dat_fmc[0]) fromMvrc.append(dat_tmc[0]) strmQ = np.zeros((len(connsp) + len(connsc))) # Hardwire the first reach to the specified inflow rate strmQ[0] = 40.0 for i, itm in enumerate(np.arange(1, len(qp[0][0]), 2)): # The first 8 reach of the parent SFR package are upstream of child grid if qp[0][0][itm][0] <= 8: strmQ[i + 1] = qp[0][0][itm][2] if i >= 8: break # The flow that is passed between the parent and child grids comes next strmQ[i] = dat_fmc[0][0][2] # Next, process the child grid for j, jtm in enumerate(np.arange(1, len(qc[0][0]), 2)): # process all reaches successively strmQ[i + (j + 1)] = qc[0][0][jtm][2] # The flow that is passed between the parent and child grids comes next from_mvr = [itm[2] for itm in dat_fmp[0] if itm[2] > 0][0] strmQ[i + j + 2] = from_mvr # Finally, process the remaining parent model stream reaches for k, ktm in enumerate(np.arange(15, len(qp[0][0]), 2)): strmQ[i + j + 2 + (k + 1)] = qp[0][0][ktm][2] # Fill out a single vector of stream reach lengths all_rch_lengths = rlen[0:8] + rlenc + rlen[8:] # Now get center of all the reaches rch_lengths = [] for i in np.arange(len(all_rch_lengths)): rch_lengths.append( np.sum(all_rch_lengths[0:i]) + (all_rch_lengths[i] / 2)) # Make a continuous vector of the gw-sw exchanges gwsw_exg = np.zeros((len(connsp) + len(connsc))) for i, itm in enumerate(gwswp[0]): if itm[0] <= 8: gwsw_exg[i] = itm[2] elif itm[0] > 8: gwsw_exg[(len(gwsw_exg) - (len(gwswp[0]) - i))] = itm[2] # Insert the child model gw/sw exchages in their proper sequential spot for j, jtm in enumerate(gwswc[0]): gwsw_exg[8 + j] = jtm[2] fig, ax1 = plt.subplots(figsize=figure_size, dpi=300, tight_layout=True) pts = ax1.plot(rch_lengths, strmQ, "r^", label="Stream Flow", zorder=3) ax1.set_zorder(4) ax1.set_facecolor("none") ax1.text( rch_lengths[int(len(rch_lengths) / 2)], 160, "Local Grid Refinement", ha="center", fontsize=10, ) ax1.arrow(1080, 163, -440, 0, head_width=5, head_length=50, fc="k", ec="k") ax1.arrow(2150, 163, 395, 0, head_width=5, head_length=50, fc="k", ec="k") ax1.arrow( 525, 27, 80, -7, head_width=5, head_length=50, fc="deeppink", ec="deeppink", linewidth=2, ) # deeppink ax1.arrow( 2550, 130, 80, 7, head_width=5, head_length=50, fc="deeppink", ec="deeppink", linewidth=2, ) ax1.text( ((rch_lengths[7] + rch_lengths[8]) / 2) + 50, 27, "First MVR\ntransfer", ha="left", fontsize=10, ) ax1.text( (rch_lengths[7] + rch_lengths[8]) / 2 + 15, 180 + 3.5, "Child Grid", rotation=90, ha="left", fontsize=10, ) ax1.text( (rch_lengths[7] + rch_lengths[8]) / 2, 180, "Parent Grid", rotation=90, ha="right", fontsize=10, ) ax1.text( ((rch_lengths[96] + rch_lengths[97]) / 2) + 100, 130, "Second MVR\ntransfer", ha="left", fontsize=10, ) ax1.text( (rch_lengths[96] + rch_lengths[97]) / 2 + 15, 180, "Parent Grid", rotation=90, ha="left", fontsize=10, ) ax1.text( (rch_lengths[96] + rch_lengths[97]) / 2, 180 + 3.5, "Child Grid", rotation=90, ha="right", fontsize=10, ) ax1.set_xlim([0, 3500]) ax1.set_ylim([-110, 250]) ax1.set_xlabel("Distance Along River ($m$)") ax1.set_ylabel(r"Stream Flow ($\frac{m^3}{s}$)") ax1.vlines( x=(rch_lengths[7] + rch_lengths[8]) / 2, ymin=-60, ymax=235, linewidth=2, ) ax1.vlines( x=(rch_lengths[96] + rch_lengths[97]) / 2, ymin=-65, ymax=235, linewidth=2, ) ax2 = ax1.twinx() ax2.set_xlim([0, 3500]) ax2.set_ylim([-11, 25]) # [itm/10 for itm in all_rch_lengths] bar = ax2.bar( rch_lengths, gwsw_exg, align="center", color="b", width=[itm / 2 for itm in all_rch_lengths], label="GW-SW Exchange", ) ax2.set_zorder(2) ax2.set_axisbelow(True) ax2.set_ylabel( r"Groundwater Surface-Water Exchange by Stream Reach ($\frac{m^3}{s}$)", rotation=270, labelpad=15, ) ax2.yaxis.grid(color="silver", zorder=1) lns = pts + [bar] labs = [l.get_label() for l in lns] leg = ax2.legend(lns, labs, loc="lower right", frameon=True) leg.get_frame().set_linewidth(0.0) title = "River conditions with steady flow" letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}{}".format(sim_name, config.figure_ext)) fig.savefig(fpth)
def plot_results(mt3d, mf6, idx, ax=None): if config.plotModel: mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join(mf6_out_path, list(mf6.model_names)[1] + ".ucn") ucnobj_mf6 = flopy.utils.HeadFile(fname_mf6, precision="double", text="CONCENTRATION") # Get the MT3DMS observation output file fname = os.path.join(mt3d_out_path, "MT3D001.OBS") if os.path.isfile(fname): cvt = mt3d.load_obs(fname) else: cvt = None # Get the MODFLOW 6 concentration observation output file fname = os.path.join(mf6_out_path, list(mf6.model_names)[1] + ".obs.csv") mf6cobs = np.genfromtxt(fname, delimiter=",", names=True) times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) x = cvt["time"] / 365.0 y = cvt["(1, 16, 16)"] # Pare down the list length to clean plot x_pare = x[::20] y_pare = y[::20] ax.plot(x_pare, y_pare, label="Upstream FD", marker="^") # Add MF6 output x_mf6 = mf6cobs["time"] / 365.0 y_mf6 = mf6cobs["BCKGRND_CN"] x_mf6_pare = x_mf6[::20] y_mf6_pare = y_mf6[::20] ax.plot( x_mf6_pare, y_mf6_pare, label="MODFLOW 6", marker="x", linestyle=":", ) plt.xlim(0, 10) plt.ylim(0, 100.0) plt.xlabel("Time, in years") plt.ylabel("Normalized Concentration, in percent") plt.legend() title = "Calculated Concentration at an Injection/Pumping Well" letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
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_results(mt3d, mf6, idx, ax=None, ax2=None): if config.plotModel: mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output gwt = mf6.get_model(list(mf6.model_names)[1]) ucnobj_mf6 = gwt.output.concentration() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) conc1 = conc_mt3d[0, 0, :, :] conc2 = conc_mf6[0, 0, :, :] x = (mt3d.modelgrid.xcellcenters[15, 15:] - mt3d.modelgrid.xcellcenters[15, 15]) y_mt3d = conc1[15, 15:] y_mf6 = conc2[15, 15:] plt.plot(x, y_mt3d, label="MT3DMS", marker="o") plt.plot(x, y_mf6, label="MODFLOW 6", marker="^", color="k") ax.set_ylim(0, 1.025) plt.xlabel("Radial Distance From The Source, in meters") plt.ylabel("Normalized Concentration, unitless") plt.legend() title = "Concentration as a Function of Distance From The Source" letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-xsec", config.figure_ext), ) fig.savefig(fpth) # second plot if ax2 is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax2 = fig.add_subplot(1, 1, 1, aspect="equal") levels = np.arange(0.2, 1, 0.2) mm = flopy.plot.PlotMapView(model=mt3d) mm.plot_grid(color=".5", alpha=0.2) mm.plot_ibound() cs1 = mm.contour_array(conc_mt3d[0], levels=levels, colors="r") plt.clabel(cs1, inline=1, fontsize=10) cs2 = mm.contour_array(conc_mf6[0], levels=levels, colors="k", linestyles=":") plt.clabel(cs2, inline=1, fontsize=10) labels = ["MT3DMS", "MODFLOW 6"] lines = [cs1.collections[0], cs2.collections[0]] plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") title = "Comparison of MT3DMS and MF6 isoconcentration lines" ax2.legend(lines, labels, loc="upper left") # draw line representing location of cross-section shown in previous figure plt.plot([155, 300], [155, 155], "k-", lw=2) # Add labels to the plot # style = dict(size=10, color='black') # ax2.text(235, 140, "Location of x-section \nshown in Fig. x", **style) letter = chr(ord("@") + idx + 2) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-planView", 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_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["totim"], hb[key], color="#238A8DFF", lw=1.25, label=otext) ax.plot( es["totim"], 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_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=(5.5, 8.0)) ax = fig.add_subplot(2, 2, 1, aspect="equal") pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=0) pmv.plot_grid() pmv.plot_bc(name="WEL", kper=3) pmv.plot_bc(name="RIV") title = "Layer 1" letter = chr(ord("@") + 1) fs.heading(letter=letter, heading=title, ax=ax) ax.set_xlabel("x position (m)") ax.set_ylabel("y position (m)") ax = fig.add_subplot(2, 2, 2, aspect="equal") pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=1) pmv.plot_grid() pmv.plot_bc(name="GHB") title = "Layer 2" letter = chr(ord("@") + 2) fs.heading(letter=letter, heading=title, ax=ax) ax.set_xlabel("x position (m)") ax.set_ylabel("y position (m)") ax = fig.add_subplot(2, 2, 3, aspect="equal") pmv = flopy.plot.PlotMapView(model=gwf, ax=ax, layer=2) pmv.plot_grid() pmv.plot_bc(name="GHB") pmv.plot_bc(ftype="WEL", kper=3) title = "Layer 3" letter = chr(ord("@") + 3) fs.heading(letter=letter, heading=title, ax=ax) ax.set_xlabel("x position (m)") ax.set_ylabel("y position (m)") ax = fig.add_subplot(2, 2, 4, aspect="equal") pmv = flopy.plot.PlotMapView(model=gwf, ax=ax) pmv.plot_grid(linewidth=0) for ip, (p, fc) in enumerate([ (recharge_zone_1, "r"), (recharge_zone_2, "b"), (recharge_zone_3, "g"), ]): xs, ys = p.exterior.xy ax.fill( xs, ys, alpha=0.25, fc=fc, ec="none", label="Recharge Zone {}".format(ip + 1), ) ax.set_xlabel("x position (m)") ax.set_ylabel("y position (m)") fs.graph_legend(ax) title = "Recharge zones" letter = chr(ord("@") + 4) fs.heading(letter=letter, heading=title, ax=ax) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) fig.savefig(fpth) return
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_sfr_results(gwf, silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations fpth = os.path.join(ws, sim_name, "{}.sfr.obs.csv".format(sim_name)) results = np.genfromtxt(fpth, delimiter=",", names=True) # modify the time results["time"] /= 365.25 * 86400.0 rnos = ( 3, 14, 26, 35, ) sfr = gwf.sfr.packagedata.array["rtp"] offsets = [] for rno in rnos: offsets.append(sfr[rno]) # create the figure fig, axes = plt.subplots( ncols=2, nrows=4, sharex=True, figsize=(6.3, 6.3), constrained_layout=True, ) ipos = 0 for i in range(4): heading = "Reach {}".format(rnos[i] + 1) for j in range(2): ax = axes[i, j] ax.set_xlim(0, 100) if j == 0: tag = "R{:02d}_STAGE".format(i + 1) offset = offsets[i] scale = 1.0 ylabel = "Reach depth, in feet" color = "blue" else: tag = "R{:02d}_FLOW".format(i + 1) offset = 0.0 scale = -1.0 ylabel = "Downstream reach flow,\nin cubic feet per second" color = "red" ax.plot( results["time"], scale * results[tag] - offset, lw=0.5, color=color, zorder=10, ) ax.axvline(50, lw=0.5, ls="--", color="black", zorder=10) if ax.get_ylim()[0] < 0.0: ax.axhline(0, lw=0.5, color="0.5", zorder=9) fs.add_text( ax, text="Pumping", x=0.49, y=0.8, ha="right", bold=False, fontsize=7, ) fs.add_text( ax, text="Recovery", x=0.51, y=0.8, ha="left", bold=False, fontsize=7, ) ax.set_ylabel(ylabel) ax.yaxis.set_label_coords(-0.1, 0.5) fs.heading(ax, heading=heading, idx=ipos) if i == 3: ax.set_xlabel("Time since pumping began, in years") ipos += 1 # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-02{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_results(mt3d, mf6, idx, ax=None): if config.plotModel: mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join(mf6_out_path, list(mf6.model_names)[1] + ".ucn") ucnobj_mf6 = flopy.utils.HeadFile(fname_mf6, precision="double", text="CONCENTRATION") times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1, aspect="equal") mm = flopy.plot.PlotMapView(model=mt3d) mm.plot_grid(color=".5", alpha=0.2) cs1 = mm.contour_array(conc_mt3d[1], levels=[0.1, 1.0, 10.0, 50.0], colors="k") plt.clabel(cs1, inline=1, fontsize=10) cs2 = mm.contour_array( conc_mf6[1], levels=[0.1, 1.0, 10.0, 50.0], colors="r", linestyles="--", ) plt.clabel(cs2, inline=1, fontsize=10) labels = ["MT3DMS", "MODFLOW 6"] lines = [cs1.collections[0], cs2.collections[0]] plt.xlabel("DISTANCE ALONG X-AXIS, IN METERS") plt.ylabel("DISTANCE ALONG Y-AXIS, IN METERS") title = "Plume at Time = 365 " + "{}".format(time_units) ax.legend(lines, labels, loc="upper left") # ax.plot(np.linspace(0, l, ncol), conc_mt3d[0,0,0,:], color='k', label='MT3DMS') # ax.plot(np.linspace(0, l, ncol), conc_mf6[0,0,0,:], '^', color='b', label='MF6') # ax.set_ylim(0, 1.2) # ax.set_xlim(0, 1000) # ax.set_xlabel('Distance, in m') # ax.set_ylabel('Concentration') # title = 'Concentration Profile at Time = 1,000 ' + '{}'.format( # time_units) # ax.legend() letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}{}".format(sim_name, config.figure_ext)) fig.savefig(fpth)
def plot_gwt_results(sims): if config.plotModel: print("Plotting model results...") sim_mf6gwf, sim_mf6gwt = sims gwf = sim_mf6gwf.flow gwt = sim_mf6gwt.trans fs = USGSFigure(figure_type="map", verbose=False) sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path() fname = os.path.join(sim_ws, "trans.ucn") conc = flopy.utils.HeadFile( fname, text="concentration", precision="double" ) conc = conc.get_data() fname = os.path.join(sim_ws, "trans.lkt.bin") lakconc = flopy.utils.HeadFile( fname, text="concentration", precision="double" ) lakconc = lakconc.get_data().flatten() il, jl = np.where(lakibd > 0) for i, j in zip(il, jl): ilak = lakibd[i, j] - 1 lake_conc = lakconc[ilak] conc[0, i, j] = lake_conc fig, axs = plt.subplots( 2, 2, figsize=(5, 7), dpi=300, tight_layout=True ) for iplot, ilay in enumerate([0, 2, 4, 7]): ax = axs.flatten()[iplot] pmv = plot_bcmap(ax, gwf, ilay) levels = levels = [ 1, 10, 25, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, ] cs = pmv.contour_array( conc, colors="blue", linestyles="-", levels=levels, linewidths=1.0, masked_values=[1.0e30], ) ax.clabel(cs, cs.levels[::1], fmt="%1.0f", colors="b") title = "Model Layer {}".format(ilay + 1) letter = chr(ord("@") + iplot + 1) fs.heading(letter=letter, heading=title, ax=ax) # axs[1, 1].set_axis_off() # save figure if config.plotSave: sim_folder = os.path.split(sim_ws)[0] sim_folder = os.path.basename(sim_folder) fname = "{}-conc{}".format(sim_folder, config.figure_ext) fpth = os.path.join(ws, "..", "figures", fname) fig.savefig(fpth) fname = "trans.lkt.bin" fname = os.path.join(sim_ws, fname) bobj = flopy.utils.HeadFile( fname, precision="double", text="concentration" ) lkaconc = bobj.get_alldata()[:, 0, 0, :] bobj.file.close() fname = "trans.sft.bin" fname = os.path.join(sim_ws, fname) bobj = flopy.utils.HeadFile( fname, precision="double", text="concentration" ) sfaconc = bobj.get_alldata()[:, 0, 0, :] times = bobj.times bobj.file.close() fs = USGSFigure(figure_type="graph", verbose=False) fig, axs = plt.subplots( 1, 1, figsize=(5, 3), dpi=300, tight_layout=True ) ax = axs times = np.array(times) / 365.0 ax.plot( times, lkaconc[:, 0], "b-", label="Lake 1 and Stream Segment 2" ) ax.plot(times, sfaconc[:, 30], "r-", label="Stream Segment 3") ax.plot(times, sfaconc[:, 37], "g-", label="Stream Segment 4") fname = os.path.join(data_ws, "teststrm.sg2") sg = np.genfromtxt(fname, comments='"') ax.plot(sg[:, 0] / 365.0, sg[:, 6], "b--") fname = os.path.join(data_ws, "teststrm.sg3") sg = np.genfromtxt(fname, comments='"') ax.plot(sg[:, 0] / 365.0, sg[:, 6], "r--") fname = os.path.join(data_ws, "teststrm.sg4") sg = np.genfromtxt(fname, comments='"') ax.plot(sg[:, 0] / 365.0, sg[:, 3], "g--") fs.graph_legend() ax.set_ylim(0, 50) ax.set_xlim(0, 25) ax.set_xlabel("TIME, IN YEARS") ax.set_ylabel( "SIMULATED BORON CONCENTRATION,\nIN MICROGRAMS PER LITER" ) # save figure if config.plotSave: sim_folder = os.path.split(sim_ws)[0] sim_folder = os.path.basename(sim_folder) fname = "{}-cvt{}".format(sim_folder, config.figure_ext) fpth = os.path.join(ws, "..", "figures", fname) fig.savefig(fpth)
def plot_results(mf2k5, mt3d, mf6, idx, ax=None): if config.plotModel: mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join(mf6_out_path, list(mf6.model_names)[1] + ".ucn") ucnobj_mf6 = flopy.utils.HeadFile(fname_mf6, precision="double", text="CONCENTRATION") times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] axWasNone = False if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(3, 1, 1, aspect="equal") axWasNone = True ilay = 4 mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay) mm.plot_grid(color=".5", alpha=0.2) mm.plot_ibound() cs1 = mm.contour_array(conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors="k") cs2 = mm.contour_array( conc_mf6[0], levels=[0.01, 0.05, 0.15, 0.50], colors="r", linestyles=":", ) plt.clabel(cs1) plt.xlabel("DISTANCE ALONG X-AXIS, IN METERS") plt.ylabel("DISTANCE ALONG Y-AXIS, IN METERS") title = "Layer {}".format(ilay + 1) letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) labels = ["MT3DMS", "MODFLOW 6"] lines = [cs1.collections[0], cs2.collections[0]] ax.legend(lines, labels, loc="upper center") if axWasNone: ax = fig.add_subplot(3, 1, 2, aspect="equal") ilay = 5 mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay) mm.plot_grid(color=".5", alpha=0.2) mm.plot_ibound() cs = mm.contour_array(conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors="k") cs = mm.contour_array( conc_mf6[0], levels=[0.01, 0.05, 0.15, 0.50], colors="r", linestyles=":", ) plt.clabel(cs) plt.xlabel("DISTANCE ALONG X-AXIS, IN METERS") plt.ylabel("DISTANCE ALONG Y-AXIS, IN METERS") title = "Layer {}".format(ilay + 1) letter = chr(ord("@") + idx + 2) fs.heading(letter=letter, heading=title) if axWasNone: ax = fig.add_subplot(3, 1, 3, aspect="equal") ilay = 6 mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5, layer=ilay) mm.plot_grid(color=".5", alpha=0.2) mm.plot_ibound() cs = mm.contour_array(conc_mt3d[0], levels=[0.01, 0.05, 0.15, 0.50], colors="k") cs = mm.contour_array( conc_mf6[0], levels=[0.01, 0.05, 0.15, 0.50], colors="r", linestyles=":", ) plt.clabel(cs) plt.xlabel("DISTANCE ALONG X-AXIS, IN METERS") plt.ylabel("DISTANCE ALONG Y-AXIS, IN METERS") title = "Layer {}".format(ilay + 1) letter = chr(ord("@") + idx + 3) fs.heading(letter=letter, heading=title) plt.plot( mf2k5.modelgrid.xcellcenters[7, 2], mf2k5.modelgrid.ycellcenters[7, 2], "ko", ) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name, 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(mf2k5, mt3d, mf6, idx, ax=None): if config.plotModel: print("Plotting model results...") mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join( mf6_out_path, list(mf6.model_names)[1] + ".ucn" ) ucnobj_mf6 = flopy.utils.HeadFile( fname_mf6, precision="double", text="CONCENTRATION" ) times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() hk = mf2k5.lpf.hk.array # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] levels = np.arange(0.2, 10, 0.4) stp_idx = 0 # 0-based (out of 2 possible stress periods) # Plot after 8 years axWasNone = False if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 2, 1, aspect="equal") axWasNone = True ax = fig.add_subplot(1, 2, 1, aspect="equal") cflood = np.ma.masked_less_equal(conc_mt3d[stp_idx], 0.2) mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5) mm.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mm.plot_ibound() mm.plot_grid(color=".5", alpha=0.2) cs = mm.plot_array(cflood[0], alpha=0.5, vmin=0, vmax=3) cs = mm.contour_array(conc_mt3d[stp_idx], colors="k", levels=levels) plt.clabel(cs) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") title = "MT3D - End of SP " + str(stp_idx + 1) letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) if axWasNone: ax = fig.add_subplot(1, 2, 2, aspect="equal") cflood = np.ma.masked_less_equal(conc_mf6[stp_idx], 0.2) mm = flopy.plot.PlotMapView(ax=ax, model=mf2k5) mm.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mm.plot_ibound() mm.plot_grid(color=".5", alpha=0.2) cs = mm.plot_array(cflood[0], alpha=0.5, vmin=0, vmax=3) cs = mm.contour_array(conc_mf6[stp_idx], colors="k", levels=levels) plt.clabel(cs) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") title = "MODFLOW 6 - End of SP " + str(stp_idx + 1) letter = chr(ord("@") + idx + 2) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".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 file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # 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_results(mf6, idx): if config.plotModel: print("Plotting model results...") sim_name = mf6.name fs = USGSFigure(figure_type="graph", verbose=False) # Generate a plot of FINF distribution finf_plt = finf_grad.copy() finf_plt[idomain1 == 0] = np.nan fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) plt.imshow(finf_plt, cmap="jet") title = "Precipitation distribution" cbar = plt.colorbar(shrink=0.5) cbar.ax.set_title("Infiltration\nrate\nfactor", pad=20) plt.xlabel("Column Number") plt.ylabel("Row Number") fs.heading(heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-finfFact", config.figure_ext), ) fig.savefig(fpth) # Start by retrieving some output mf6_out_pth = mf6.simulation_data.mfpath.get_sim_path() mod_bud_file = list(mf6.model_names)[0] + ".bud" sfr_bud_file = list(mf6.model_names)[0] + ".sfr.bud" uzf_bud_file = list(mf6.model_names)[0] + ".uzf.bud" hed_file = list(mf6.model_names)[0] + ".hds" mod_out = os.path.join(mf6_out_pth, mod_bud_file) sfr_out = os.path.join(mf6_out_pth, sfr_bud_file) uzf_out = os.path.join(mf6_out_pth, uzf_bud_file) hds_out = os.path.join(mf6_out_pth, hed_file) modobj = bf.CellBudgetFile(mod_out, precision="double") sfrobj = bf.CellBudgetFile(sfr_out, precision="double") uzfobj = bf.CellBudgetFile(uzf_out, precision="double") hdsobj = bf.HeadFile(hds_out) ckstpkper = modobj.get_kstpkper() hds = [] depths = [] hd_tmp = hdsobj.get_data(kstpkper=ckstpkper[0]) hd_tmp = np.where(hd_tmp == 1e30, 0, hd_tmp) hds.append(hd_tmp) depths.append(top - hd_tmp[0, :, :]) depths = np.array(depths) depths = depths[0, :, :] # Generate a plot of the gw table depths for the steady state stress per depths[idomain1 == 0] = np.nan fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) plt.imshow(depths, vmin=0, vmax=25, cmap="jet") cbar = plt.colorbar(shrink=0.5, ticks=[0, 5, 10, 15, 20, 25]) cbar.ax.set_yticklabels(["0", "5", "10", "15", "20", "> 25"]) cbar.ax.set_title("Depth to\nwater\ntable,\nin m", pad=20) plt.xlabel("Column Number") plt.ylabel("Row Number") title = "Depth To Groundwater" fs.heading(heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-gwDepth", config.figure_ext), ) fig.savefig(fpth) drn_disQ = [] uzrech = [] finf_tot = [] sfr_gwsw = [] sfr_flow = [] rejinf = [] uzet = [] gwet = [] outflow = [] for kstpkper in ckstpkper: # 1. Compile groundwater discharge to land surface drn_tmp = modobj.get_data(kstpkper=kstpkper, text=" DRN-TO-MVR") drn_arr = np.zeros_like(top) for itm in drn_tmp[0]: i, j = drn_dict_rev[itm[1] - 1] drn_arr[i, j] = itm[2] drn_disQ.append(drn_arr) # 2. Compile groundwater discharge to stream cells sfr_tmp = sfrobj.get_data(kstpkper=kstpkper, text=" GWF") sfr_arr = np.zeros_like(top) for x, itm in enumerate(sfr_tmp[0]): i = sfrcells[x][1] j = sfrcells[x][2] sfr_arr[i, j] = itm[2] sfr_gwsw.append(sfr_arr) # 3. Compile Infiltrated amount uzf_tmp = uzfobj.get_data(kstpkper=kstpkper, text=" INFILTRATION") finf_arr = np.zeros_like(top) for itm in uzf_tmp[0]: i, j = iuzno_dict_rev[itm[0] - 1] finf_arr[i, j] = itm[2] finf_tot.append(finf_arr) # 4. Compile recharge from UZF uzrch_tmp = uzfobj.get_data(kstpkper=kstpkper, text=" GWF") uzrch_arr = np.zeros_like(top) for itm in uzrch_tmp[0]: i, j = iuzno_dict_rev[itm[0] - 1] uzrch_arr[i, j] = itm[2] uzrech.append(uzrch_arr) # 5. Compile rejected infiltration rejinf_tmp = uzfobj.get_data(kstpkper=kstpkper, text=" REJ-INF-TO-MVR") rejinf_arr = np.zeros_like(top) for itm in rejinf_tmp[0]: i, j = iuzno_dict_rev[itm[0] - 1] rejinf_arr[i, j] = itm[2] rejinf.append(rejinf_arr) # 6. Compile unsat ET uzet_tmp = uzfobj.get_data(kstpkper=kstpkper, text=" UZET") uzet_arr = np.zeros_like(top) for itm in uzet_tmp[0]: i, j = iuzno_dict_rev[itm[0] - 1] uzet_arr[i, j] = itm[2] uzet.append(uzet_arr) # 7. Compile groundwater ET gwet_tmp = modobj.get_data(kstpkper=kstpkper, text=" UZF-GWET") gwet_arr = np.zeros_like(top) for itm in gwet_tmp[0]: i, j = iuzno_dict_rev[itm[1] - 1] gwet_arr[i, j] = itm[2] gwet.append(gwet_arr) # 8. Get flows at outlet outletQ = sfrobj.get_data(kstpkper=kstpkper, text=" FLOW-JA-FACE") outflow.append(outletQ[0][-1][2]) drn_disQ = np.array(drn_disQ) sfr_gwsw = np.array(sfr_gwsw) finf_tot = np.array(finf_tot) uzrech = np.array(uzrech) rejinf = np.array(rejinf) uzet = np.array(uzet) gwet = np.array(gwet) outflow = np.array(outflow) drn_disQ_ts = drn_disQ.sum(axis=-1).sum(axis=-1) sfr_gwsw_ts = sfr_gwsw.sum(axis=-1).sum(axis=-1) finf_tot_ts = finf_tot.sum(axis=-1).sum(axis=-1) uzrech_ts = uzrech.sum(axis=-1).sum(axis=-1) rejinf_ts = rejinf.sum(axis=-1).sum(axis=-1) uzet_ts = uzet.sum(axis=-1).sum(axis=-1) gwet_ts = gwet.sum(axis=-1).sum(axis=-1) rng = pd.date_range(start="11/1/1999", end="10/31/2000", freq="D") data = { "Recharge": abs(uzrech_ts[0:366]), "Infiltration": abs(finf_tot_ts[0:366]), "GroundwaterET": abs(gwet_ts[0:366]), "UnsaturatedZoneET": abs(uzet_ts[0:366]), } vals1 = pd.DataFrame(data, index=rng) fig = plt.figure(figsize=figure_size_ts, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) vals1.Infiltration.plot(style="k-", linewidth=0.3) vals1.Recharge.plot(style="b-", linewidth=0.7) vals1.GroundwaterET.plot(style="-", color="darkgreen", linewidth=0.7, label="Groundwater ET") vals1.UnsaturatedZoneET.plot(style="-", color="orange", linewidth=1, label="Unsaturated Zone ET") ax.set_ylim(0, 700000) plt.tick_params( axis="x", # changes apply to the x-axis which="both", # both major and minor ticks are affected bottom=False, # ticks along the bottom edge are off top=False, # ticks along the top edge are off labelbottom=True, ) # labels along the bottom edge are off ax.set_xlabel("Month") ax.set_ylabel("Volumetric Rate, $m^3$ per day") fs.graph_legend(ax) title = "Unsaturated Zone Flow Budget" fs.heading(heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-uzFlow", config.figure_ext), ) fig.savefig(fpth) data_sfr = { "GroundwaterDischarge": abs(drn_disQ_ts[0:366]), "RejectedInfiltration": abs(rejinf_ts[0:366]), "gwswExchange": abs(sfr_gwsw_ts[0:366]), "outflow": outflow[0:366], } vals2 = pd.DataFrame(data_sfr, index=rng) fig = plt.figure(figsize=figure_size_ts, dpi=300, tight_layout=True) ax = fig.add_subplot(1, 1, 1) vals2.outflow.plot( style="-", linewidth=0.5, color="royalblue", label="Streamflow at Outlet", ) vals2.GroundwaterDischarge.plot(style="k-", linewidth=0.7, label="Groundwater Discharge") vals2.RejectedInfiltration.plot( style="-", linewidth=0.7, color="brown", label="Rejected Infiltration", ) vals2.gwswExchange.plot( style="-", color="darkgreen", linewidth=0.7, label="GW Discharge to Streams", ) ax.set_ylim(0, 350000) plt.tick_params( axis="x", # changes apply to the x-axis which="both", # both major and minor ticks are affected bottom=False, # ticks along the bottom edge are off top=False, # ticks along the top edge are off labelbottom=True, ) # labels along the bottom edge are off ax.set_xlabel("Month") ax.set_ylabel("Volumetric Rate, $m^3$ per day") fs.graph_legend(ax) title = "Surface Water Flow" fs.heading(heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name + "-swFlow", config.figure_ext), ) fig.savefig(fpth)
def plot_results(mf2k5, mt3d, mf6, idx, ax=None): if config.plotModel: print("Plotting model results...") mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join(mf6_out_path, list(mf6.model_names)[1] + ".ucn") ucnobj_mf6 = flopy.utils.HeadFile(fname_mf6, precision="double", text="CONCENTRATION") times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] levels = np.arange(0.2, 10, 0.4) stp_idx = 0 # 0-based (out of 2 possible stress periods) cinit = mt3d.btn.sconc[0].array[2] # Plots of concentration axWasNone = False if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(2, 2, 1, aspect="equal") axWasNone = True mm = flopy.plot.PlotMapView(model=mf2k5) mm.plot_grid(color=".5", alpha=0.2) cs = mm.contour_array(cinit, levels=np.arange(20, 200, 20)) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.clabel(cs, fmt=r"%3d") sr = mf2k5.dis.sr for k, i, j, q in mf2k5.wel.stress_period_data[0]: plt.plot(sr.xcenter[j], sr.ycenter[i], "ks") title = "Layer 3 Initial Concentration" letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # 2nd figure if axWasNone: ax = fig.add_subplot(2, 2, 2, aspect="equal") c = conc_mt3d[1, 2] # Layer 3 @ 500 days (2nd specified output time) mm = flopy.plot.PlotMapView(model=mf2k5) mm.plot_grid(color=".5", alpha=0.2) cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), color="black") plt.clabel(cs1, fmt=r"%3d") c_mf6 = conc_mf6[1, 2] # Layer 3 @ 500 days cs2 = mm.contour_array(c_mf6, levels=np.arange(10, 200, 10), color="red", linestyles="--") labels = ["MT3DMS", "MODFLOW 6"] lines = [cs1.collections[0], cs2.collections[0]] ax.legend(lines, labels, loc="upper left") plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") for k, i, j, q in mf2k5.wel.stress_period_data[0]: plt.plot(sr.xcenter[j], sr.ycenter[i], "ks") title = "MT3D Layer 3 Time = 500 days" letter = chr(ord("@") + idx + 2) fs.heading(letter=letter, heading=title) # 3rd figure if axWasNone: ax = fig.add_subplot(2, 2, 3, aspect="equal") c = conc_mt3d[2, 2] mm = flopy.plot.PlotMapView(model=mf2k5) mm.plot_grid(color=".5", alpha=0.2) cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), color="black") plt.clabel(cs1, fmt=r"%3d") c_mf6 = conc_mf6[2, 2] cs2 = mm.contour_array(c_mf6, levels=np.arange(10, 200, 10), color="red", linestyles="--") plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") for k, i, j, q in mf2k5.wel.stress_period_data[0]: plt.plot(sr.xcenter[j], sr.ycenter[i], "ks") title = "MT3D Layer 3 Time = 750 days" letter = chr(ord("@") + idx + 3) fs.heading(letter=letter, heading=title) # 4th figure if axWasNone: ax = fig.add_subplot(2, 2, 4, aspect="equal") c = conc_mt3d[3, 2] mm = flopy.plot.PlotMapView(model=mf2k5) mm.plot_grid(color=".5", alpha=0.2) cs1 = mm.contour_array(c, levels=np.arange(10, 200, 10), color="black") plt.clabel(cs1, fmt=r"%3d") c_mf6 = conc_mf6[3, 2] cs2 = mm.contour_array(c_mf6, levels=np.arange(10, 200, 10), color="red", linestyles="--") plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") for k, i, j, q in mf2k5.wel.stress_period_data[0]: plt.plot(sr.xcenter[j], sr.ycenter[i], "ks") title = "MT3D Layer 3 Time = 1,000 days" letter = chr(ord("@") + idx + 4) fs.heading(letter=letter, heading=title) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format( sim_name, config.figure_ext, ), ) fig.savefig(fpth)
def plot_results(mt3d, mf6, idx, ax=None): if config.plotModel: mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) times_mt3d = ucnobj_mt3d.get_times() conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output fname_mf6 = os.path.join( mf6_out_path, list(mf6.model_names)[1] + ".ucn" ) ucnobj_mf6 = flopy.utils.HeadFile( fname_mf6, precision="double", text="CONCENTRATION" ) times_mf6 = ucnobj_mf6.get_times() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name if ax is None: fig, ax = plt.subplots( 1, 1, figsize=figure_size, dpi=300, tight_layout=True ) ax.plot( np.linspace(0, l, ncol), conc_mt3d[0, 0, 0, :], color="k", label="MT3DMS", linewidth=0.5, ) ax.plot( np.linspace(0, l, ncol), conc_mf6[0, 0, 0, :], "^", markeredgewidth=0.5, color="blue", fillstyle="none", label="MF6", markersize=3, ) ax.set_ylim(0, 1.2) ax.set_xlim(0, 1000) ax.set_xlabel("Distance, in m") ax.set_ylabel("Concentration") title = "Concentration Profile at Time = 2,000 " + "{}".format( time_units ) ax.legend() letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name, config.figure_ext) ) fig.savefig(fpth)
def plot_results(sim, mf, 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) # 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-2005 head object fpth = os.path.join(sim_ws, "mf2005", file_name) hobj0 = 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") # create MODFLOW-2005 cell-by-cell budget object fpth = os.path.join(sim_ws, "mf2005", file_name) cobj0 = flopy.utils.CellBudgetFile(fpth, precision="double") # extract heads head = hobj.get_data() head0 = hobj0.get_data() vmin, vmax = -25, 100 # check that the results are comparable for idx, k in enumerate( ( 0, 2, 4, ) ): diff = np.abs(head[k] - head0[idx]) msg = "aquifer {}: ".format( idx + 1 ) + "maximum absolute head difference is {}".format(diff.max()) assert diff.max() < 0.05, msg if not silent: print(msg) # extract specific discharge spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=(0, 0)) frf = cobj0.get_data(text="FLOW RIGHT FACE", kstpkper=(0, 0))[0] fff = cobj0.get_data(text="FLOW FRONT FACE", kstpkper=(0, 0))[0] flf = cobj0.get_data(text="FLOW LOWER FACE", kstpkper=(0, 0))[0] # modflow 6 layers to extract layers_mf6 = [0, 2, 4] titles = ["Unconfined aquifer", "Middle aquifer", "Lower aquifer"] # Create figure for simulation extents = (0, ncol * delc, 0, nrow * delr) fig, axes = plt.subplots( 3, 3, figsize=figure_size, dpi=300, constrained_layout=True, sharey=True, ) for ax in axes.flatten(): ax.set_aspect("equal") ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) for idx, ax in enumerate(axes.flatten()[:3]): k = layers_mf6[idx] fmp = flopy.plot.PlotMapView( model=gwf, ax=ax, layer=k, extent=extents ) ax.get_xaxis().set_ticks([]) fmp.plot_grid(lw=0.5) plot_obj = fmp.plot_array(head, vmin=vmin, vmax=vmax) fmp.plot_bc("DRN", color="green") fmp.plot_bc("WEL", color="0.5") cv = fmp.contour_array( head, levels=[-25, 0, 25, 75, 100], linewidths=0.5, colors="black", ) plt.clabel(cv, fmt="%1.0f") fmp.plot_specific_discharge(spdis, normalize=True, color="0.75") title = titles[idx] letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title, ax=ax) for idx, ax in enumerate(axes.flatten()[3:6]): fmp = flopy.plot.PlotMapView( model=mf, ax=ax, layer=idx, extent=extents ) fmp.plot_grid(lw=0.5) plot_obj = fmp.plot_array(head0, vmin=vmin, vmax=vmax) fmp.plot_bc("DRN", color="green") fmp.plot_bc("WEL", color="0.5") cv = fmp.contour_array( head0, levels=[-25, 0, 25, 75, 100], linewidths=0.5, colors="black", ) plt.clabel(cv, fmt="%1.0f") fmp.plot_discharge( frf, fff, flf, head=head0, normalize=True, color="0.75" ) title = titles[idx] letter = chr(ord("@") + idx + 4) fs.heading(letter=letter, heading=title, ax=ax) # create legend ax = plt.subplot(313) ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) # ax = axes.flatten()[-2] ax.axis("off") ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="green", mec="green", label="Drain", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="0.5", mec="0.5", label="Well", ) 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") # plot colorbar cax = plt.axes([0.325, 0.125, 0.35, 0.025]) cbar = plt.colorbar( plot_obj, shrink=0.8, orientation="horizontal", cax=cax ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $ft$", fontsize=9) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format(sim_name, config.figure_ext) ) fig.savefig(fpth)
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_results(mf2k5, mt3d, mf6, idx, ax=None): if config.plotModel: print("Plotting model results...") mt3d_out_path = mt3d.model_ws mf6_out_path = mf6.simulation_data.mfpath.get_sim_path() mf6.simulation_data.mfpath.get_sim_path() # Get the MT3DMS concentration output fname_mt3d = os.path.join(mt3d_out_path, "MT3D001.UCN") ucnobj_mt3d = flopy.utils.UcnFile(fname_mt3d) conc_mt3d = ucnobj_mt3d.get_alldata() # Get the MF6 concentration output gwt = mf6.get_model(list(mf6.model_names)[1]) ucnobj_mf6 = gwt.output.concentration() conc_mf6 = ucnobj_mf6.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) sim_name = mf6.name plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] hk = mf2k5.lpf.hk.array # Which year to plot?: yr_idx = [7, 11, 19] # 0-based contourLevels = np.arange(0.05, 0.5, 0.05) # Plot after 8 years i = 0 axWasNone = False if ax is None: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(2, 1, 1) axWasNone = True mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MT3D-USGS" ) letter = chr(ord("@") + idx + 1) fs.heading(letter=letter, heading=title) if axWasNone: ax = fig.add_subplot(2, 1, 2) mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MODFLOW 6" ) letter = chr(ord("@") + idx + 2) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format( sim_name + "-" + str(yr_idx[i] + 1) + "yrs", config.figure_ext, ), ) fig.savefig(fpth) # Plot after 12 years i = 1 if axWasNone: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(2, 1, 1) axWasNone = True mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MT3D-USGS" ) letter = chr(ord("@") + idx + 3) fs.heading(letter=letter, heading=title) if axWasNone: ax = fig.add_subplot(2, 1, 2) mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MODFLOW 6" ) letter = chr(ord("@") + idx + 4) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format( sim_name + "-" + str(yr_idx[i] + 1) + "yrs", config.figure_ext, ), ) fig.savefig(fpth) # Plot after 20 years i = 2 if axWasNone: fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) ax = fig.add_subplot(2, 1, 1) axWasNone = True mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mt3d[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MT3D-USGS" ) letter = chr(ord("@") + idx + 5) fs.heading(letter=letter, heading=title) if axWasNone: ax = fig.add_subplot(2, 1, 2) mx = flopy.plot.PlotCrossSection(ax=ax, model=mf2k5, line={"row": 0}) mx.plot_array(hk, masked_values=[hk[0, 0, 0]], alpha=0.2) mx.plot_ibound() mx.plot_grid(color="0.5", alpha=0.2) cs = mx.contour_array( conc_mf6[yr_idx[i]], levels=contourLevels, masked_values=[1.0e30] ) plt.clabel(cs, fmt=r"%4.2f") title = ( "Migrating plume after " + str(yr_idx[i] + 1) + " years, MODFLOW 6" ) letter = chr(ord("@") + idx + 6) fs.heading(letter=letter, heading=title) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}{}".format( sim_name + "-" + str(yr_idx[i] + 1) + "yrs", config.figure_ext, ), ) fig.savefig(fpth)
def plot_conc_results(sims, idx): print("Plotting conc model results...") sim_mf6gwf, sim_mf6gwt, sim_mf2005, sim_mt3dms = sims gwf = sim_mf6gwf.flow gwt = sim_mf6gwt.trans botm = gwf.dis.botm.array fs = USGSFigure(figure_type="map", verbose=False) head = gwf.output.head().get_data() head = np.where(head > botm, head, np.nan) sim_ws = sim_mf6gwt.simulation_data.mfpath.get_sim_path() cobj = gwt.output.concentration() conc_times = cobj.get_times() conc_times = np.array(conc_times) fig, axes = plt.subplots( 3, 1, figsize=(7.5, 4.5), dpi=300, tight_layout=True ) xgrid, _, zgrid = gwt.modelgrid.xyzcellcenters # Desired plot times plot_times = [100.0, 1000.0, 3000.0] nplots = len(plot_times) for iplot in range(nplots): print(" Plotting conc {}".format(iplot + 1)) time_in_pub = plot_times[iplot] idx_conc = (np.abs(conc_times - time_in_pub)).argmin() totim = conc_times[idx_conc] ax = axes[iplot] pxs = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={"row": 0}) conc = cobj.get_data(totim=totim) conc = np.where(head > botm, conc, np.nan) pa = pxs.plot_array(conc, head=head, cmap="jet", vmin=0, vmax=1.0) pxs.plot_bc(ftype="RCH", color="red") pxs.plot_bc(ftype="CHD") confining_rect = matplotlib.patches.Rectangle( (3000, 1000), 3000, 100, color="gray", alpha=0.5 ) ax.add_patch(confining_rect) if iplot == 2: ax.set_xlabel("x position (m)") ax.set_ylabel("elevation (m)") title = "Time = {}".format(totim) letter = chr(ord("@") + iplot + 1) fs.heading(letter=letter, heading=title, ax=ax) ax.set_aspect(plotaspect) for k, i, j in [obs1, obs2]: x = xgrid[i, j] z = zgrid[k, i, j] ax.plot( x, z, markerfacecolor="yellow", markeredgecolor="black", marker="o", markersize="4", ) # save figure if config.plotSave: sim_folder = os.path.split(sim_ws)[0] sim_folder = os.path.basename(sim_folder) fname = "{}-conc{}".format(sim_folder, config.figure_ext) fpth = os.path.join(ws, "..", "figures", fname) fig.savefig(fpth)
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_difference_conc(sim): conc_singlemodel_lay3 = get_reference_data_conc() # Get the concentration output gwt_outer = sim.get_model(gwtname_out) gwt = sim.get_model(gwtname_inn) ucnobj_mf6 = gwt.output.concentration() conc_mf6 = ucnobj_mf6.get_alldata() ucnobj_mf6_outer = gwt_outer.output.concentration() conc_mf6_outer = ucnobj_mf6_outer.get_alldata() # Create figure for scenario fs = USGSFigure(figure_type="graph", verbose=False) plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) # Difference in concentration @ 1 day ax = fig.add_subplot(2, 2, 1, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) istep = 0 ilayer = 2 c_1day = conc_mf6_outer[istep] c_1day[:, 8:53, 6:34] = conc_mf6[istep] c_1day_singlemodel_lay3 = conc_singlemodel_lay3[istep] pa = mm.plot_array(c_1day[ilayer] - c_1day_singlemodel_lay3) xc, yc = gwt.modelgrid.xycenters plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.colorbar(pa, shrink=0.5) # Plot the wells as well for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Difference Layer 3 Time = 1 day" fs.heading(letter='A', heading=title) # Difference in concentration @ 500 days ax = fig.add_subplot(2, 2, 2, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) istep = 1 ilayer = 2 c_500days = conc_mf6_outer[istep] c_500days[:, 8:53, 6:34] = conc_mf6[istep] c_500days_singlemodel_lay3 = conc_singlemodel_lay3[istep] pa = mm.plot_array(c_500days[ilayer] - c_500days_singlemodel_lay3) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.colorbar(pa, shrink=0.5) for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Difference Layer 3 Time = 500 days" fs.heading(letter='B', heading=title) # Difference in concentration @ 750 days ax = fig.add_subplot(2, 2, 3, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) istep = 2 ilayer = 2 c_750days = conc_mf6_outer[istep] c_750days[:, 8:53, 6:34] = conc_mf6[istep] c_750days_singlemodel_lay3 = conc_singlemodel_lay3[istep] pa = mm.plot_array(c_750days[ilayer] - c_750days_singlemodel_lay3) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.colorbar(pa, shrink=0.5) for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Difference Layer 3 Time = 750 days" fs.heading(letter='C', heading=title) # Difference in concentration @ 1000 days ax = fig.add_subplot(2, 2, 4, aspect="equal") mm = flopy.plot.PlotMapView(model=gwt_outer) mm.plot_grid(color=".5", alpha=0.2) istep = 3 ilayer = 2 c_1000days = conc_mf6_outer[istep] c_1000days[:, 8:53, 6:34] = conc_mf6[istep] c_1000days_singlemodel_lay3 = conc_singlemodel_lay3[istep] pa = mm.plot_array(c_1000days[ilayer] - c_1000days_singlemodel_lay3) plt.xlim(5100, 5100 + 28 * 50) plt.ylim(9100, 9100 + 45 * 50) plt.xlabel("Distance Along X-Axis, in meters") plt.ylabel("Distance Along Y-Axis, in meters") plt.colorbar(pa, shrink=0.5) for cid, f, c in welspd_mf6: plt.plot(xshift + xc[cid[2]], yshift + yc[cid[1]], "ks") title = "Difference Layer 3 Time = 1000 days" fs.heading(letter='D', heading=title) fpath = os.path.join("..", "figures", "ex-gwtgwt-p10-diffconc.png") fig.savefig(fpath) return
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)