def plot_ts(sim): fs = USGSFigure(figure_type="graph", verbose=False) sim_ws = os.path.join(ws, sim_name) gwf = sim.get_model(sim_name) ylabel = ["head (m)", "flow ($m^3/d$", "flow ($m^3/d$"] for iplot, obstype in enumerate(["obs.head", "obs.flow", "ghb.obs"]): fig = plt.figure(figsize=(6, 3)) ax = fig.add_subplot() fname = os.path.join(sim_ws, "{}.{}.csv".format(sim_name, obstype)) tsdata = np.genfromtxt(fname, names=True, delimiter=",") for name in tsdata.dtype.names[1:]: ax.plot(tsdata["time"], tsdata[name], label=name) ax.set_xlabel("time (d)") ax.set_ylabel(ylabel[iplot]) fs.graph_legend(ax) if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{}{}".format( sim_name, obstype.replace(".", "-"), config.figure_ext ), ) fig.savefig(fpth) return
def plot_ts(sim): fs = USGSFigure(figure_type="graph", verbose=False) sim_ws = os.path.join(ws, sim_name) gwf = sim.get_model(sim_name) obsnames = gwf.obs[1].output.obs_names obs_list = [ gwf.obs[1].output.obs(f=obsnames[0]), gwf.obs[1].output.obs(f=obsnames[1]), gwf.ghb.output.obs(), ] ylabel = ("head (m)", "flow ($m^3/d$)", "flow ($m^3/d$)") obs_fig = ("obs-head", "obs-flow", "ghb-obs") for iplot, obstype in enumerate(obs_list): fig = plt.figure(figsize=(6, 3)) ax = fig.add_subplot() tsdata = obstype.data for name in tsdata.dtype.names[1:]: ax.plot(tsdata["totim"], tsdata[name], label=name) ax.set_xlabel("time (d)") ax.set_ylabel(ylabel[iplot]) fs.graph_legend(ax) if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{}{}".format(sim_name, obs_fig[iplot], config.figure_ext), ) fig.savefig(fpth) return
def plot_boundary_heads(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) def process_dtw_obs(fpth): v = np.genfromtxt(fpth, names=True, delimiter=",") v["time"] /= 365.25 v["time"] += 1908.353182752 for key in v.dtype.names[1:]: v[key] *= -1.0 return v name = list(parameters.keys())[0] pth = os.path.join(ws, name, "{}.gwf.obs.csv".format(name)) hdata = process_dtw_obs(pth) pheads = ("HD01", "HD12", "HD14") hlabels = ("Upper aquifer", "Middle aquifer", "Lower aquifer") hcolors = ("green", "cyan", "blue") fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6.8, 6.8 / 3)) ax.set_xlim(1907, 2007) ax.set_xticks(xticks) ax.set_ylim(50.0, -10.0) ax.set_yticks(sorted([50.0, 40.0, 30.0, 20.0, 10.0, 0.0, -10.0])) ax.plot([1907, 2007], [0, 0], lw=0.5, color="0.5") for idx, key in enumerate(pheads): ax.plot( hdata["time"], hdata[key], lw=0.75, color=hcolors[idx], label=hlabels[idx], ) fs.graph_legend(ax=ax, frameon=False) ax.set_ylabel("Depth to water, in {}".format(length_units)) ax.set_xlabel("Year") fs.remove_edge_ticks(ax=ax) fig.tight_layout() # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_regional_grid(silent=True): if silent: verbosity = 0 else: verbosity = 1 name = list(parameters.keys())[0] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load( sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity ) gwf = sim.get_model(sim_name) # get regional heads for constant head boundaries h = gwf.output.head().get_data() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(6.3, 3.5), ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 6))] # legend axis axes.append(fig.add_subplot(nrows, ncols, (7, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotCrossSection(gwf, ax=ax, line={"row": 0}) ca = mm.plot_array(h, head=h) mm.plot_bc("CHD", color="cyan", head=h) mm.plot_grid(lw=0.5, color="0.5") cv = mm.contour_array( h, levels=np.arange(0, 6, 0.5), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.1f") ax.plot( [50, 150, 150, 50, 50], [10, 10, aq_bottom, aq_bottom, 10], lw=1.25, color="#39FF14", ) fs.remove_edge_ticks(ax) ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("Elevation, in feet") # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="none", mec="0.5", markeredgewidth=0.5, label="Grid cell", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="0.5", markeredgewidth=0.5, label="Constant head", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="none", mec="#39FF14", markeredgewidth=1.25, label="Local model domain", ) ax.plot( -10000, -10000, lw=0.5, color="black", label="Head contour, $ft$", ) cbar = plt.colorbar(ca, shrink=0.5, orientation="horizontal", ax=ax) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $ft$", fontsize=9) fs.graph_legend(ax, loc="lower center", ncol=4) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-regional-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_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_comp_q_comparison(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name thicknesses = parameters[name]["bed_thickness"] # get the subdirectory names hb_dirs, es_dirs = get_subdirs(sim) # setup the figure fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(1, 2, figure=fig) # set color cmap = plt.get_cmap("viridis") cNorm = mpl.colors.Normalize(vmin=0, vmax=6) scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap) axes = [] for idx in range(2): ax = fig.add_subplot(gs[idx]) if idx == 0: ax.set_yticks(np.arange(-0.40, 0.1, 0.05)) ax.set_ylim(-0.40, 0) ax.set_xlim(0, 100) ylabel = ("Head-based minus effective stress-based\nsubsidence, " + "in percent of ultimate value") else: ax.set_ylim(0, 8) ax.set_xlim(0, 100) ylabel = ( "Top minus bottom interbed effective stress-based\ndrainage " + "rate, in percent of head-based drainage rate") ax.set_xlabel("Percent of time constant") ax.set_ylabel(ylabel) fs.heading(ax, letter=chr(ord("A") + idx)) axes.append(ax) for idx, (hb_dir, es_dir) in enumerate(zip(hb_dirs, es_dirs)): sim_ws = os.path.join(ws, name, hb_dir) s = flopy.mf6.MFSimulation().load(sim_ws=sim_ws, verbosity_level=0) g = s.get_model(name) hb_obs = g.csub.output.obs().data ws0 = os.path.join(ws, name, es_dir) s0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0) g0 = s0.get_model(name) es_obs = g0.csub.output.obs().data # calculate normalized simulation time tpct = hb_obs["totim"] * 100 / tau0 thickness = thicknesses[idx] if idx == 0: color = "black" else: color = scalarMap.to_rgba(idx - 1) label = "Thickness = {:>3d} m".format(int(thickness)) v = 100.0 * (hb_obs["TCOMP"] - es_obs["TCOMP"]) / (skv * thickness) ax = axes[0] ax.plot(tpct, v, color=color, lw=0.75, label=label) denom = hb_obs["QTOP"] + hb_obs["QBOT"] v = 100 * (es_obs["QTOP"] - es_obs["QBOT"]) / denom ax = axes[1] ax.plot(tpct, v, color=color, lw=0.75, label=label) # legend ax = axes[-1] leg = fs.graph_legend(ax, loc="upper right") # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_maw_results(silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations fpth = os.path.join(ws, sim_name, "{}.maw.obs.csv".format(sim_name)) maw = np.genfromtxt(fpth, delimiter=",", names=True) time = maw["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(0, 4500) ax.semilogx( time, maw["Q1"], lw=0.75, ls="-", color="blue", label="Upper aquifer", ) ax.semilogx( time, maw["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, idx=0) # fs.graph_legend(ax, loc="upper right", ncol=2) ax = axes[1] ax.set_xlim(tmin, tmax) ax.set_ylim(-4500, 0) ax.axhline( 10.0, lw=0.75, ls="-", color="blue", label="Upper aquifer", ) ax.axhline( 10.0, lw=0.75, ls="-", color="red", label="Lower aquifer", ) ax.semilogx( time, maw["FW"], lw=0.75, ls="-", color="black", label="Flowing well discharge", ) ax.set_xlabel(" ") ax.set_ylabel(" ") for axis in (ax.xaxis,): axis.set_major_formatter(mpl.ticker.ScalarFormatter()) fs.heading(ax, idx=1) fs.graph_legend(ax, loc="upper left", ncol=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_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_head_based(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name # get csub observations ws = sim.simulation_data.mfpath.get_sim_path() s = flopy.mf6.MFSimulation().load(sim_ws=ws, verbosity_level=0) gwf = s.get_model(name) cobs = gwf.csub.output.obs().data # calculate the compaction analytically ac = [] nz = 100 thick = parameters[name]["bed_thickness"][0] kv = parameters[name]["kv"][0] dhalf = thick * 0.5 az = np.linspace(-dhalf, dhalf, num=nz) dz = az[1] - az[0] for tt in cobs["totim"]: c = 0.0 for jdx, zz in enumerate(az): f = 1.0 if jdx == 0 or jdx == nz - 1: f = 0.5 h = analytical_solution(zz, tt, ssk=skv, vk=kv, n=200, dh=1.0) c += h * skv * f * dz ac.append(c) ac = np.array(ac) # calculate normalized simulation time tpct = cobs["totim"] * 100 / tau0 # plot the results fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(1, 2, figure=fig) idx = 0 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * ac / skv, marker=".", lw=0, ms=3, color="red", label="Analytical", ) ax.plot( tpct, 100 * cobs["TCOMP"] / skv, label="Simulated", color="black", lw=1, zorder=100, ) leg = fs.graph_legend(ax, loc="lower right") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel("Compaction, in percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 100) fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) idx += 1 ax = fig.add_subplot(gs[idx]) ax.plot(tpct, 100 * (ac - cobs["TCOMP"]) / skv, lw=1, ls=":", color="black") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 2.2, 0.2)) ax.set_xlabel("Percent of time constant") ax.set_ylabel( "Analytical minus simulated subsidence,\nin percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 2) fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_results(idx, sim, silent=True): verbose = not silent if config.plotModel: fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[idx] sim_ws = os.path.join(ws, name) gwf = sim.get_model(sim_name) bot = gwf.dis.botm.array if idx == 0: plot_grid(gwf, silent=silent) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") # extract heads and specific discharge head = hobj.get_data(totim=1.0) imask = (head > -1e30) & (head <= bot) head[imask] = -1e30 # botm[imask] spdis = cobj.get_data(text="DATA-SPDIS", totim=1.0) # Create figure for simulation fig, axes = create_figure() ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) if bot.max() < 20: cv = mm.contour_array( bot, levels=blevels, linewidths=0.5, linestyles=":", colors=bcolor, zorder=9, ) plt.clabel(cv, fmt="%1.0f", zorder=9) h_coll = mm.plot_array(head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10) cv = mm.contour_array( head, masked_values=masked_values, levels=vlevels, linewidths=0.5, linestyles="-", colors=vcolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) mm.plot_specific_discharge(spdis, normalize=True, color="0.75", zorder=11) ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.remove_edge_ticks(ax) # create legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) if bot.max() < 20: ax.plot( -10000, -10000, lw=0.5, ls=":", color=bcolor, label="Bottom elevation contour, m", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color=vcolor, label="Head contour, m", ) fs.graph_legend(ax, loc="center", ncol=2) cax = plt.axes([0.275, 0.125, 0.45, 0.025]) cbar = plt.colorbar(h_coll, shrink=0.8, orientation="horizontal", cax=cax) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $m$", fontsize=9) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{:02d}{}".format(sim_name, idx + 1, config.figure_ext), ) fig.savefig(fpth)
def plot_gwseep_results(silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations name = list(parameters.keys())[0] fpth = os.path.join(ws, name, "{}.surfrate.obs.csv".format(sim_name)) drn = np.genfromtxt(fpth, delimiter=",", names=True) name = list(parameters.keys())[1] fpth = os.path.join(ws, name, "{}.surfrate.obs.csv".format(sim_name)) uzf = np.genfromtxt(fpth, delimiter=",", names=True) time = drn["time"] / 86400.0 q0 = drn["SURFRATE"] q1 = uzf["SURFRATE"] mean_error = np.mean(q0 - q1) # create the figure fig, axes = plt.subplots( ncols=2, nrows=1, sharex=True, figsize=(6.3, 3.15), constrained_layout=True, ) ax = axes[0] ax.set_xlim(0, 365) ax.set_ylim(0, 175) xp, yp = [0.0], [uzf["NETINFIL"][0]] for idx in range(time.shape[0]): if idx == 0: x0, x1 = 0.0, time[idx] else: x0, x1 = time[idx - 1], time[idx] y2 = uzf["NETINFIL"][idx] xp.append(x0) xp.append(x1) yp.append(y2) yp.append(y2) ax.fill_between( [x0, x1], 0, y2=y2, lw=0, color="blue", step="post", ec="none", zorder=100, ) ax.plot(xp, yp, lw=0.5, color="black", zorder=101) plot_stress_periods(ax) fs.heading(ax, idx=0) ax.set_xlabel("Simulation time, in days") ax.set_ylabel( "Infiltration to the unsaturated zone,\nin cubic feet per second" ) ax = axes[-1] ax.set_xlim(0, 365) ax.set_ylim(50.8, 51.8) ax.plot( time, -drn["SURFRATE"], lw=0.75, ls="-", color="blue", label="Drainage package", ) ax.plot( time, -uzf["SURFRATE"], marker="o", ms=3, mfc="none", mec="black", markeredgewidth=0.5, lw=0.0, ls="-", color="red", label="UZF groundwater seepage", ) plot_stress_periods(ax) fs.graph_legend( ax, loc="upper center", ncol=1, frameon=True, edgecolor="none" ) fs.heading(ax, idx=1) fs.add_text( ax, "Mean Error {:.2e} cubic feet per second".format(mean_error), bold=False, italic=False, x=1.0, y=1.01, va="bottom", ha="right", fontsize=7, ) ax.set_xlabel("Simulation time, in days") ax.set_ylabel( "Groundwater seepage to the land surface,\nin cubic feet per second" ) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) 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), ("STAGE", float), ("A", float), ("B", float), ] results = np.zeros((lak_results.shape[0] + 1), dtype=dtype) results["time"][1:] = lak_results["time"] results["STAGE"][0] = 110.0 results["STAGE"][1:] = lak_results["STAGE"] results["A"][0] = 115.0 results["A"][1:] = gwf_results["A"] results["B"][0] = 115.0 results["B"][1:] = gwf_results["B"] # create the figure fig, ax = plt.subplots( ncols=1, nrows=1, sharex=True, figsize=(6.3, 3.15), constrained_layout=True, ) ax.set_xlim(0, 3000) ax.set_ylim(110, 160) ax.plot( results["time"], results["STAGE"], lw=0.75, ls="--", color="black", label="Lake stage", ) 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.set_xlabel("Simulation time, in days") ax.set_ylabel("Head or stage, in feet") fs.graph_legend(ax, loc="lower right") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_grid(gwf, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) bot = gwf.dis.botm.array fig, axes = create_figure() ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) bot_coll = mm.plot_array(bot, vmin=bmin, vmax=bmax) mm.plot_bc("CHD", color="cyan") cv = mm.contour_array( bot, levels=blevels, linewidths=0.5, linestyles=":", colors=bcolor, ) plt.clabel(cv, fmt="%1.0f") ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.remove_edge_ticks(ax) # legend ax = axes[1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0.5, ls=":", color=bcolor, label="Bottom elevation contour, m", ) fs.graph_legend(ax, loc="center", ncol=2) cax = plt.axes([0.275, 0.125, 0.45, 0.025]) cbar = plt.colorbar( bot_coll, shrink=0.8, orientation="horizontal", cax=cax, ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Bottom Elevation, $m$") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_grid(gwf, silent=True): sim_ws = os.path.join(ws, sim_name) # load the observations fpth = os.path.join(ws, sim_name, "{}.lak.obs.csv".format(sim_name)) lak_results = np.genfromtxt(fpth, delimiter=",", names=True) # create MODFLOW 6 head object file_name = gwf.oc.head_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) hobj = flopy.utils.HeadFile(fpth) # create MODFLOW 6 cell-by-cell budget object file_name = gwf.oc.budget_filerecord.get_data()[0][0] fpth = os.path.join(sim_ws, file_name) cobj = flopy.utils.CellBudgetFile(fpth, precision="double") kstpkper = hobj.get_kstpkper() head = hobj.get_data(kstpkper=kstpkper[0]) spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0]) # add lake stage to heads head[head == 1e30] = lak_results["STAGE"][-1] # observation locations xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1] p1 = (xcenters[3], ycenters[3]) p2 = (xcenters[13], ycenters[13]) fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(4, 6.9), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 5))] axes.append(fig.add_subplot(nrows, ncols, (6, 8), sharex=axes[0])) for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) if idx == 0: ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (9, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) mm.plot_bc("CHD", color="cyan") mm.plot_inactive(color_noflow="#5DBB63") mm.plot_grid(lw=0.5, color="black") cv = mm.contour_array( head, levels=np.arange(140, 160, 2), linewidths=0.75, linestyles="-", colors="blue", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_specific_discharge(spdis, normalize=True, color="0.75") ax.plot(p1[0], p1[1], marker="o", mfc="red", mec="black", ms=4) ax.plot(p2[0], p2[1], marker="o", mfc="red", mec="black", ms=4) ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.heading(ax, heading="Map view", idx=0) fs.add_text( ax, "A", x=p1[0] + 150, y=p1[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.add_text( ax, "B", x=p2[0] + 150, y=p2[1] + 150, transform=False, bold=False, color="red", ha="left", va="bottom", ) fs.remove_edge_ticks(ax) ax = axes[1] xs = flopy.plot.PlotCrossSection(gwf, ax=ax, line={"row": 8}) xs.plot_array(np.ones(shape3d), head=head, cmap="jet") xs.plot_bc("CHD", color="cyan", head=head) xs.plot_ibound(color_noflow="#5DBB63", head=head) xs.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") ax.set_ylim(67, 160) ax.set_ylabel("Elevation, in feet") fs.heading(ax, heading="Cross-section view", idx=1) fs.remove_edge_ticks(ax) # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="#5DBB63", mec="black", markeredgewidth=0.5, label="Lake boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="black", markeredgewidth=0.5, label="Constant-head boundary", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="blue", mec="black", markeredgewidth=0.5, label="Water table", ) ax.plot( -10000, -10000, lw=0, marker="o", ms=4, mfc="red", mec="black", markeredgewidth=0.5, label="Observation well", ) ax.plot( -10000, -10000, lw=0.75, ls="-", color="blue", label=r"Head contour, $ft$", ) ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) fs.graph_legend(ax, loc="lower center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_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_local_grid(silent=True): if silent: verbosity = 0 else: verbosity = 1 name = list(parameters.keys())[1] sim_ws = os.path.join(ws, name) sim = flopy.mf6.MFSimulation.load( sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity ) gwf = sim.get_model(sim_name) i, j = maw_loc dx, dy = delr[j], delc[i] px = ( 50.0 - 0.5 * dx, 50.0 + 0.5 * dx, ) py = ( 0.0 + dy, 0.0 + dy, ) # get regional heads for constant head boundaries h = gwf.output.head().get_data() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(6.3, 4.1), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 8))] for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (8, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents, layer=0) mm.plot_bc("CHD", color="cyan", plotAll=True) mm.plot_grid(lw=0.25, color="0.5") cv = mm.contour_array( h, levels=np.arange(4.0, 5.0, 0.005), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.3f") ax.fill_between( px, py, y2=0, ec="none", fc="red", lw=0, zorder=200, step="post" ) fs.add_annotation( ax, text="Well location", xy=(50.0, 0.0), xytext=(55, 5), bold=False, italic=False, ha="left", fontsize=7, arrowprops=arrow_props, ) fs.remove_edge_ticks(ax) ax.set_xticks([0, 25, 50, 75, 100]) ax.set_xlabel("x-coordinate, in feet") ax.set_yticks([0, 25, 50]) ax.set_ylabel("y-coordinate, in feet") # legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="0.5", markeredgewidth=0.25, label="Constant head", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="red", mec="0.5", markeredgewidth=0.25, label="Multi-aquifer well", ) ax.plot( -10000, -10000, lw=0.5, color="black", label="Water-table contour, $ft$", ) fs.graph_legend(ax, loc="lower center", ncol=3) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-local-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_grid(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(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="map", verbose=verbose) name = sim.name gwf = sim.get_model(name) extents = gwf.modelgrid.extent # read simulated heads pth = os.path.join(ws, name, "{}.hds".format(name)) hobj = flopy.utils.HeadFile(pth) h0 = hobj.get_data(kstpkper=(0, 0)) h1 = hobj.get_data(kstpkper=(59, 1)) hsxs0 = h0[0, 8, :] hsxs1 = h1[0, 8, :] # get delr array dx = gwf.dis.delr.array # create x-axis for cross-section hxloc = np.arange(1000, 2000.0 * 15, 2000.0) # set cross-section location y = 2000.0 * 11.5 xsloc = [(extents[0], extents[1]), (y, y)] # well locations w1loc = (9.5 * 2000.0, 11.75 * 2000.0) w2loc = (6.5 * 2000.0, 8.5 * 2000.0) fig = plt.figure(figsize=(6.8, 5), constrained_layout=True) gs = mpl.gridspec.GridSpec(7, 10, figure=fig, wspace=5) plt.axis("off") ax = fig.add_subplot(gs[:, 0:6]) # ax.set_aspect('equal') mm = flopy.plot.PlotMapView(model=gwf, ax=ax, extent=extents) mm.plot_grid(lw=0.5, color="0.5") mm.plot_bc(ftype="WEL", kper=1, plotAll=True) mm.plot_bc(ftype="CHD", color="blue") mm.plot_bc(ftype="RCH", color="green") mm.plot_inactive(color_noflow="0.75") mm.ax.plot(xsloc[0], xsloc[1], color="orange", lw=1.5) # contour steady state heads cl = mm.contour_array( h0, masked_values=[1.0e30], levels=np.arange(115, 200, 5), colors="black", linestyles="dotted", linewidths=0.75, ) ax.clabel(cl, fmt="%3i", inline_spacing=0.1) # well text fs.add_annotation( ax=ax, text="Well 1, layer 2", bold=False, italic=False, xy=w1loc, xytext=(w1loc[0] - 3200, w1loc[1] + 1500), ha="right", va="center", zorder=100, arrowprops=arrow_props, ) fs.add_annotation( ax=ax, text="Well 2, layer 4", bold=False, italic=False, xy=w2loc, xytext=(w2loc[0] + 3000, w2loc[1]), ha="left", va="center", zorder=100, arrowprops=arrow_props, ) ax.set_ylabel("y-coordinate, in meters") ax.set_xlabel("x-coordinate, in meters") fs.heading(ax, letter="A", heading="Map view") fs.remove_edge_ticks(ax) ax = fig.add_subplot(gs[0:5, 6:]) mm = flopy.plot.PlotCrossSection(model=gwf, ax=ax, line={"row": 8}) mm.plot_grid(lw=0.5, color="0.5") # items for legend mm.ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="Recharge", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="blue", mec="black", mew=0.5, label="Constant head", ) mm.ax.plot( -1000, -1000, "s", ms=5, color="0.75", mec="black", mew=0.5, label="Inactive", ) mm.ax.plot( [-1000, -1001], [-1000, -1000], color="orange", lw=1.5, label="Cross-section line", ) # aquifer coloring ax.fill_between([0, dx.sum()], y1=150, y2=-100, color="cyan", alpha=0.5) ax.fill_between([0, dx.sum()], y1=-100, y2=-150, color="#D2B48C", alpha=0.5) ax.fill_between([0, dx.sum()], y1=-150, y2=-350, color="#00BFFF", alpha=0.5) # well coloring ax.fill_between([dx.cumsum()[8], dx.cumsum()[9]], y1=50, y2=-100, color="red", lw=0) # labels fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-97, text="Upper aquifer", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-147, text="Confining unit", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=300, y=-347, text="Lower aquifer", va="bottom", ha="left", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=53, text="Layer 1", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-97, text="Layer 2", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-147, text="Layer 3", va="bottom", ha="right", fontsize=9, ) fs.add_text( ax=ax, transform=False, bold=False, italic=False, x=29850, y=-347, text="Layer 4", va="bottom", ha="right", fontsize=9, ) ax.plot( hxloc, hsxs0, lw=0.75, color="black", ls="dotted", label="Steady-state\nwater level", ) ax.plot( hxloc, hsxs1, lw=0.75, color="black", ls="dashed", label="Water-level at the end\nof stress-period 2", ) ax.set_ylabel("Elevation, in meters") ax.set_xlabel("x-coordinate along model row 9, in meters") fs.graph_legend( mm.ax, ncol=2, bbox_to_anchor=(0.5, -0.6), borderaxespad=0, frameon=False, loc="lower center", ) fs.heading(ax, letter="B", heading="Cross-section view") fs.remove_edge_ticks(ax) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-grid{}".format(sim_name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_results(idx, sim, silent=True): verbose = not silent if config.plotModel: fs = USGSFigure(figure_type="map", verbose=verbose) name = list(parameters.keys())[idx] sim_ws = os.path.join(ws, name) gwf = sim.get_model(sim_name) bot = gwf.dis.botm.array if idx == 0: plot_grid(gwf, silent=silent) plot_recharge(gwf, silent=silent) # create MODFLOW 6 head object hobj = gwf.output.head() # get times times = hobj.get_times() # extract heads and specific discharge head = hobj.get_data(totim=times[0]) imask = head <= bot + 0.001 head[imask] = -1e30 sat_thick = head - botm sat_thick[imask] = -1e30 # Create figure for simulation fig, axes = create_figure(nsubs=2, size=figure_size) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) h_coll = mm.plot_array(head, vmin=vmin, vmax=vmax, masked_values=masked_values, zorder=10) cv = mm.contour_array( head, masked_values=masked_values, levels=vlevels, linewidths=0.5, linestyles="-", colors=vcolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) cbar = plt.colorbar( h_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Water level, $m$") ax.set_xlabel("x-coordinate, in meters") ax.set_ylabel("y-coordinate, in meters") fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) s_coll = mm.plot_array( sat_thick, vmin=smin, vmax=smax, masked_values=masked_values, zorder=10, ) cv = mm.contour_array( sat_thick, masked_values=masked_values, levels=slevels, linewidths=0.5, linestyles=":", colors=scolor, zorder=10, ) plt.clabel(cv, fmt="%1.0f", zorder=10) mm.plot_bc("CHD", color="cyan", zorder=11) cbar = plt.colorbar( s_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Saturated thickness, $m$") ax.set_xlabel("x-coordinate, in meters") # ax.set_ylabel("y-coordinate, in meters") fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) # create legend ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="cyan", mec="cyan", label="Constant Head", ) ax.plot( -10000, -10000, lw=0.5, ls="-", color=vcolor, label="Head contour, m", ) ax.plot( -10000, -10000, lw=0.5, ls=":", color=scolor, label="Saturated thickness contour, m", ) fs.graph_legend(ax, loc="center", ncol=3) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-{:02d}{}".format(sim_name, idx + 2, config.figure_ext), ) fig.savefig(fpth)
def plot_stresses(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name cd = get_csub_observations(sim) tmax = cd["time"][-1] fig, axes = plt.subplots( ncols=1, nrows=4, figsize=figure_size, sharex=True, constrained_layout=True, ) idx = 0 ax = axes[idx] ax.set_xlim(0, tmax) ax.set_ylim(110, 150) ax.plot( cd["time"], cd["PC1"], color="blue", lw=1, label="Preconsolidation stress", ) ax.plot(cd["time"], cd["ES1"], color="red", lw=1, label="Effective stress") fs.heading(ax, letter="A", heading="Model layer 1, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(185, 205) ax.plot(cd["time"], cd["GS1"], color="black", lw=1) fs.heading(ax, letter="B", heading="Model layer 1, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(270, 310) ax.plot(cd["time"], cd["PC2"], color="blue", lw=1) ax.plot(cd["time"], cd["ES2"], color="red", lw=1) fs.heading(ax, letter="C", heading="Model layer 2, row 9, column 10") fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(495, 515) ax.plot( [-100, -50], [-100, -100], color="blue", lw=1, label="Preconsolidation stress", ) ax.plot([-100, -50], [-100, -100], color="red", lw=1, label="Effective stress") ax.plot(cd["time"], cd["GS2"], color="black", lw=1, label="Geostatic stress") fs.graph_legend(ax, ncol=3, loc="upper center") fs.heading(ax, letter="D", heading="Model layer 2, row 9, column 10") fs.remove_edge_ticks(ax) ax.set_xlabel("Simulation time, in years") ax.set_ylabel(" ") ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[]) ax.set_ylabel("Stress, in meters of water") # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_head_results(gwf, silent=True): sim_ws = os.path.join(ws, sim_name) # create MODFLOW 6 head object hobj = gwf.output.head() # create MODFLOW 6 cell-by-cell budget object cobj = gwf.output.budget() kstpkper = hobj.get_kstpkper() fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure(figsize=figure_size, constrained_layout=False) gs = mpl.gridspec.GridSpec(ncols=10, nrows=7, figure=fig, wspace=5) plt.axis("off") axes = [fig.add_subplot(gs[:6, :5])] axes.append(fig.add_subplot(gs[:6, 5:], sharey=axes[0])) for ax in axes: ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(gs[6:, :])) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) # extract heads and specific discharge for first stress period head = hobj.get_data(kstpkper=kstpkper[0]) qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge( cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0])[0], gwf, ) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values) cv = mm.contour_array( head, levels=np.arange(900, 1100, 10), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_vector(qx, qy, normalize=True, color="0.75") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") ax.set_ylabel("y-coordinate, in feet") fs.heading(ax, heading="Steady-state", idx=0) fs.remove_edge_ticks(ax) # extract heads and specific discharge for second stress period head = hobj.get_data(kstpkper=kstpkper[1]) qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge( cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[1])[0], gwf, ) ax = axes[1] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) head_coll = mm.plot_array(head, vmin=900, vmax=1120, masked_values=masked_values) cv = mm.contour_array( head, levels=np.arange(900, 1100, 10), linewidths=0.5, linestyles="-", colors="black", masked_values=masked_values, ) plt.clabel(cv, fmt="%1.0f") mm.plot_vector(qx, qy, normalize=True, color="0.75") mm.plot_inactive(color_noflow="0.5") mm.plot_grid(lw=0.5, color="black") ax.set_xlabel("x-coordinate, in feet") fs.heading(ax, heading="Pumping", idx=1) fs.remove_edge_ticks(ax) # legend ax = axes[-1] cbar = plt.colorbar( head_coll, shrink=0.8, orientation="horizontal", ax=ax, format="%.0f", ) cbar.ax.tick_params(size=0) cbar.ax.set_xlabel(r"Head, $ft$") ax.plot( -10000, -10000, lw=0, marker=u"$\u2192$", ms=10, mfc="0.75", mec="0.75", label="Normalized specific discharge", ) ax.plot(-10000, -10000, lw=0.5, color="black", label=r"Head contour, $ft$") fs.graph_legend(ax, loc="upper center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return
def plot_compaction(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name fig, axes = plt.subplots( ncols=2, nrows=3, figsize=figure_size, sharex=True, constrained_layout=True, ) axes = axes.flatten() idx = 0 ax = axes[idx] ax.set_xlim(0, 120) ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Interbed compaction", compaction_heading[0]) fs.heading(ax, letter="A", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) fs.graph_legend(ax, ncol=2, loc="upper center") ht = "{} {}".format("Interbed compaction", compaction_heading[1]) fs.heading(ax, letter="B", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Coarse-grained compaction", compaction_heading[0]) fs.heading(ax, letter="C", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Coarse-grained compaction", compaction_heading[1]) fs.heading(ax, letter="D", heading=ht) fs.remove_edge_ticks(ax) idx += 1 ax = axes[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Total compaction", compaction_heading[0]) fs.heading(ax, letter="E", heading=ht) fs.remove_edge_ticks(ax) ax.set_ylabel(" ") ax.set_xlabel(" ") idx += 1 ax = axes.flat[idx] ax.set_ylim(0, 1) plot_compaction_values(ax, sim, tagbase=plot_tags[idx]) ht = "{} {}".format("Total compaction", compaction_heading[1]) fs.heading(ax, letter="F", heading=ht) fs.remove_edge_ticks(ax) ax = fig.add_subplot(111, frame_on=False, xticks=[], yticks=[]) ax.set_ylabel( "Downward vertical displacement at the top of the model layer, in meters" ) ax.set_xlabel("Simulation time, in years") # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-02{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_results(silent=True): if config.plotModel: verbose = not silent if silent: verbosity_level = 0 else: verbosity_level = 1 fs = USGSFigure(figure_type="map", verbose=verbose) sim_ws = os.path.join(ws, sim_name) sim = flopy.mf6.MFSimulation.load(sim_name=sim_name, sim_ws=sim_ws, verbosity_level=verbosity_level) gwf = sim.get_model(sim_name) # load the capture fraction data fpth = os.path.join(sim_ws, "capture.npz") capture = np.load(fpth)["capture"] # plot grid fig = plt.figure(figsize=(4, 3.75), constrained_layout=True) gs = mpl.gridspec.GridSpec( 2, 2, figure=fig, width_ratios=(4, 1), height_ratios=(1, 6), ) ax = fig.add_subplot(gs[:, 0]) ax.set_aspect("equal") # ax = fig.add_subplot(1, 1, 1) # ax.set_aspect("equal") mm = flopy.plot.PlotMapView(model=gwf, ax=ax) cf = mm.plot_array(capture, vmin=0, vmax=1) mm.plot_grid(lw=0.5, color="0.5") mm.plot_bc('WEL') ax.axvline(x=14.5 * delc, lw=1.25, color="cyan") mm.plot_bc('CHD', color="green") mm.plot_ibound() ax.set_ylabel("y-coordinate, in feet") ax.set_xlabel("x-coordinate, in feet") fs.remove_edge_ticks(ax) ax = fig.add_subplot(gs[0, 1]) ax.set_xlim(0, 1) ax.set_ylim(0, 1) ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) cbar = plt.colorbar(cf, ax=ax, orientation="horizontal") cbar.ax.set_xlabel("Streamflow capture fraction") ax.plot( -1000, -1000, "s", ms=5, color="green", mec="black", mew=0.5, label="Constant head", ) ax.plot( -1000, -1000, color="cyan", lw=1.25, label="River", ) ax.plot( -1000, -1000, "s", ms=5, color="red", mec="black", mew=0.5, label="Well", ) ax.plot( -1000, -1000, "s", ms=5, color="black", mec="black", mew=0.5, label="Inactive cell", ) fs.graph_legend( ax, ncol=1, frameon=False, loc="upper center", ) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(sim_name, config.figure_ext)) fig.savefig(fpth)
def plot_grid(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_effstress(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name # get effective stress csub observations gwf = sim.get_model(name) cobs = gwf.csub.output.obs().data # get head-based csub observations name0 = name.replace("-p02b", "-p02a") ws0 = os.path.join(ws, name0) sim0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0) gwf0 = sim0.get_model(name0) cobs0 = gwf0.csub.output.obs().data # calculate normalized simulation time tpct = cobs["totim"] * 100 / tau0 # plot the results fig = plt.figure(figsize=figure_size) gs = mpl.gridspec.GridSpec(1, 2, figure=fig) idx = 0 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * cobs0["TCOMP"] / skv, lw=0, marker=".", ms=3, color="#238A8DFF", label="Head-based", ) ax.plot( tpct, 100 * cobs["TCOMP"] / skv, lw=0.75, label="Effective stress-based", color="black", zorder=100, ) leg = fs.graph_legend(ax, loc="lower right") ax.set_xticks(np.arange(0, 110, 10)) ax.set_yticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel("Compaction, in percent of ultimate value") ax.set_xlim(0, 100) ax.set_ylim(0, 100) fs.heading(ax, letter="A") fs.remove_edge_ticks(ax) idx += 1 ax = fig.add_subplot(gs[idx]) ax.plot( tpct, 100 * (cobs0["TCOMP"] - cobs["TCOMP"]) / skv, lw=1, ls=":", color="black", ) ax.set_xticks(np.arange(0, 110, 10)) ax.set_xlabel("Percent of time constant") ax.set_ylabel( "Head-based minus effective stress-based\nsubsidence, in percent of ultimate value" ) ax.set_xlim(0, 100) fs.heading(ax, letter="B") fs.remove_edge_ticks(ax) plt.tight_layout() # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-01{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_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_head_comparison(sim, silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = sim.name ndcells = parameters[name]["ndelaycells"] thicknesses = parameters[name]["bed_thickness"] # get the subdirectory names hb_dirs, es_dirs = get_subdirs(sim) # setup the figure fig = plt.figure(figsize=figure_size) fig.subplots_adjust(left=0.06, right=0.95, top=0.95, bottom=0.15, wspace=0.1) gs = mpl.gridspec.GridSpec(1, 6, figure=fig) z = np.linspace(0, 1, ndcells) yticks = np.arange(0, 1.1, 0.1) # set color cmap = plt.get_cmap("viridis") cNorm = mpl.colors.Normalize(vmin=0, vmax=6) scalarMap = mpl.cm.ScalarMappable(norm=cNorm, cmap=cmap) # percentages to evaluate pct_vals = ( 1, 5, 10, 50, 100, ) axes = [] for idx in range(6): ax = fig.add_subplot(gs[idx]) ax.set_ylim(1, 0) ax.set_xlim(-5, 5) if idx < 5: fs.heading(ax, letter=chr(ord("A") + idx)) ax.set_yticks(yticks) fs.remove_edge_ticks(ax) text = r"$\frac{t}{\tau_0}$ = " + "{}".format( pct_vals[idx] / 100.0) ax.text( 0.25, 0.01, text, ha="center", va="bottom", transform=ax.transAxes, fontsize=8, ) else: ax.set_xticks([]) ax.set_yticks([]) if idx == 0: ax.set_ylabel("Interbed position, relative to interbed thickness") else: if idx == 2: text = ( "Difference in head-based and effective stress-based" + "\ninterbed heads, in percent of head-based interbed heads" ) ax.set_xlabel(text) ax.set_yticklabels([]) axes.append(ax) for idx, (hb_dir, es_dir) in enumerate(zip(hb_dirs, es_dirs)): sim_ws = os.path.join(ws, name, hb_dir) s = flopy.mf6.MFSimulation().load(sim_ws=sim_ws, verbosity_level=0) g = s.get_model(name) hb_obs = g.csub.output.obs().data hb_arr = fill_heads(hb_obs, ndcells) ws0 = os.path.join(ws, name, es_dir) s0 = flopy.mf6.MFSimulation().load(sim_ws=ws0, verbosity_level=0) g0 = s0.get_model(name) es_obs = g0.csub.output.obs().data es_arr = fill_heads(es_obs, ndcells) # # pth = os.path.join(ws, name, hb_dir, "{}.csub.obs.csv".format(name)) # hb_obs = np.genfromtxt(pth, names=True, delimiter=",") # hb_arr = fill_heads(hb_obs, ndcells) # # pth = os.path.join(ws, name, es_dir, "{}.csub.obs.csv".format(name)) # es_obs = np.genfromtxt(pth, names=True, delimiter=",") # es_arr = fill_heads(es_obs, ndcells) # calculate normalized simulation time tpct = hb_obs["totim"] * 100 / tau0 # calculate location closest to 1, 5, 10, 50, and 100 percent of time constant locs = {} for i in pct_vals: for jdx, t in enumerate(tpct): if t <= i: locs[i] = jdx for jdx, (key, ivalue) in enumerate(locs.items()): # add data to the subplot ax = axes[jdx] if idx == 0: color = "black" else: color = scalarMap.to_rgba(idx - 1) hhb = hb_arr[ivalue, :] hes = es_arr[ivalue, :] v = 100.0 * (hhb - hes) / hhb ax.plot(v, z, lw=0.75, color=color) # legend ax = axes[-1] ax.set_ylim(1, 0) ax.set_xlim(-5, 5) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) for ic, b in enumerate(thicknesses): if ic == 0: color = "black" else: color = scalarMap.to_rgba(ic - 1) label = "Thickness = {:>3d} m".format(int(b)) ax.plot([-1, -1], [-1, -1], lw=0.75, color=color, label=label) leg = fs.graph_legend(ax, loc="center", bbox_to_anchor=(0.64, 0.5)) # save figure if config.plotSave: fpth = os.path.join("..", "figures", "{}-02{}".format(name, config.figure_ext)) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_head_es_comparison(silent=True): verbose = not silent fs = USGSFigure(figure_type="graph", verbose=verbose) name = list(parameters.keys())[0] pth = os.path.join(ws, name, "{}.csub.obs.csv".format(name)) hb = process_csub_obs(pth) name = list(parameters.keys())[1] pth = os.path.join(ws, name, "{}.csub.obs.csv".format(name)) es = process_csub_obs(pth) ymin = (2.0, 1, 1, 1, 0.1, 0.1) me = {} for idx, key in enumerate(pcomp): v = (es[key] - hb[key]).mean() me[key] = v fig, axes = plt.subplots(nrows=6, ncols=1, sharex=True, figsize=(6.8, 4.7)) for idx, key in enumerate(pcomp): label = clabels[idx] ax = axes[idx] ax.set_xlim(1907, 2007) ax.set_ylim(0, ymin[idx]) ax.set_xticks(xticks) stext = "none" otext = "none" if idx == 0: stext = "Effective stress-based" otext = "Head-based" mtext = "mean error = {:7.4f} {}".format(me[key], length_units) ax.plot(hb["time"], hb[key], color="#238A8DFF", lw=1.25, label=otext) ax.plot( es["time"], es[key], color="black", lw=0.75, label=stext, zorder=101, ) ltext = chr(ord("A") + idx) htext = "{}".format(label) fs.heading(ax, letter=ltext, heading=htext) va = "bottom" ym = 0.15 if idx in [2, 3]: va = "top" ym = 0.85 ax.text( 0.99, ym, mtext, ha="right", va=va, transform=ax.transAxes, fontsize=7, ) fs.remove_edge_ticks(ax=ax) if idx == 0: fs.graph_legend(ax, loc="center left", ncol=2) if idx == 5: ax.set_xlabel("Year") axp1 = fig.add_subplot(1, 1, 1, frameon=False) axp1.tick_params( labelcolor="none", top="off", bottom="off", left="off", right="off" ) axp1.set_xlim(0, 1) axp1.set_xticks([0, 1]) axp1.set_ylim(0, 1) axp1.set_yticks([0, 1]) axp1.set_ylabel("Compaction, in {}".format(length_units)) axp1.yaxis.set_label_coords(-0.05, 0.5) fs.remove_edge_ticks(ax) fig.tight_layout(pad=0.0001) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-02{}".format(sim_name, config.figure_ext) ) if not silent: print("saving...'{}'".format(fpth)) fig.savefig(fpth)
def plot_grid(sim, silent=True): gwf = sim.get_model(sim_name) fs = USGSFigure(figure_type="map", verbose=False) fig = plt.figure( figsize=(4, 4.3), tight_layout=True, ) plt.axis("off") nrows, ncols = 10, 1 axes = [fig.add_subplot(nrows, ncols, (1, 8))] for idx, ax in enumerate(axes): ax.set_xlim(extents[:2]) ax.set_ylim(extents[2:]) ax.set_aspect("equal") # legend axis axes.append(fig.add_subplot(nrows, ncols, (9, 10))) # set limits for legend area ax = axes[-1] ax.set_xlim(0, 1) ax.set_ylim(0, 1) # get rid of ticks and spines for legend area ax.axis("off") ax.set_xticks([]) ax.set_yticks([]) ax.spines["top"].set_color("none") ax.spines["bottom"].set_color("none") ax.spines["left"].set_color("none") ax.spines["right"].set_color("none") ax.patch.set_alpha(0.0) ax = axes[0] mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents) mm.plot_bc("MAW", color="red") mm.plot_inactive(color_noflow="black") ax.set_xticks([0, extents[1] / 2, extents[1]]) ax.set_yticks([0, extents[1] / 2, extents[1]]) ax = axes[-1] ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="black", mec="black", markeredgewidth=0.5, label="Inactive cells", ) ax.plot( -10000, -10000, lw=0, marker="s", ms=10, mfc="red", mec="red", markeredgewidth=0.5, label="Multi-aquifer well", ) fs.graph_legend(ax, loc="lower center", ncol=2) # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-grid{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth)
def plot_maw_results(silent=True): fs = USGSFigure(figure_type="graph", verbose=False) # load the observations name = list(parameters.keys())[1] fpth = os.path.join(ws, name, "{}.maw.obs.csv".format(sim_name)) maw = flopy.utils.Mf6Obs(fpth).data name = list(parameters.keys())[2] fpth = os.path.join(ws, name, "{}.gwf.obs.csv".format(sim_name)) gwf = flopy.utils.Mf6Obs(fpth).data # process heads hgwf = 0.0 ihds = 0.0 for name in gwf.dtype.names: if name.startswith("H0_"): hgwf += gwf[name] ihds += 1.0 hgwf /= ihds if silent: print("MAW head: {} Average head: {}".format(maw["H0"], hgwf)) zelev = sorted(list(set(list(obs_elev.values()))), reverse=True) results = { "maw": {}, "gwf": {}, } for z in zelev: results["maw"][z] = 0.0 results["gwf"][z] = 0.0 for name in maw.dtype.names: if name.startswith("Q"): z = obs_elev[name] results["maw"][z] += 2.0 * maw[name] for name in gwf.dtype.names: if name.startswith("Q"): z = obs_elev[name] results["gwf"][z] += 2.0 * gwf[name] q0 = np.array(list(results["maw"].values())) q1 = np.array(list(results["gwf"].values())) mean_error = np.mean(q0 - q1) if silent: print("total well inflow: {}".format(q0[q0 >= 0].sum())) print("total well outflow: {}".format(q0[q0 < 0].sum())) print("total cell inflow: {}".format(q1[q1 >= 0].sum())) print("total cell outflow: {}".format(q1[q1 < 0].sum())) # create the figure fig, ax = plt.subplots( ncols=1, nrows=1, sharex=True, figsize=(4, 4), constrained_layout=True, ) ax.set_xlim(-3.5, 3.5) ax.set_ylim(-67.5, -2.5) ax.axvline(0, lw=0.5, ls=":", color="0.5") for z in np.arange(-5, -70, -5): ax.axhline(z, lw=0.5, color="0.5") ax.plot( results["maw"].values(), zelev, lw=0.75, ls="-", color="blue", label="Multi-aquifer well", ) ax.plot( results["gwf"].values(), zelev, marker="o", ms=4, mfc="red", mec="black", markeredgewidth=0.5, lw=0.0, ls="-", color="red", label="High K well", ) ax.plot( -1000, -1000, lw=0.5, ls="-", color="0.5", label="Grid cell", ) fs.graph_legend(ax, loc="upper left", ncol=1, frameon=True) fs.add_text( ax, "Mean Error {:.2e} cubic feet per day".format(mean_error), bold=False, italic=False, x=1.0, y=1.01, va="bottom", ha="right", fontsize=7, ) ax.set_xlabel("Discharge rate, in cubic feet per day") ax.set_ylabel("Elevation, in feet") # save figure if config.plotSave: fpth = os.path.join( "..", "figures", "{}-01{}".format(sim_name, config.figure_ext), ) fig.savefig(fpth) return