def plot_sfr_results(gwf, silent=True):
    fs = USGSFigure(figure_type="graph", verbose=False)

    # load the observations
    results = gwf.sfr.output.obs().data

    # modify the time
    results["totim"] /= 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["totim"],
                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_grid(sim, silent=True):
    verbose = not silent
    fs = USGSFigure(figure_type="map", verbose=verbose)
    name = sim.name
    gwf = sim.get_model(name)

    fig, ax = plt.subplots(figsize=(6.8, 2.0))
    mc = flopy.plot.PlotCrossSection(model=gwf, line={"Row": 0}, ax=ax)

    ax.fill_between([0, 1], y1=0, y2=botm, color="cyan", alpha=0.5)
    fs.add_text(
        ax=ax,
        text="Constant head",
        x=0.5,
        y=-500.0,
        bold=False,
        italic=False,
        transform=False,
        va="center",
        ha="center",
        fontsize=9,
    )
    ax.fill_between([2, 3], y1=0, y2=botm, color="cyan", alpha=0.5)
    fs.add_text(
        ax=ax,
        text="Constant head",
        x=2.5,
        y=-500.0,
        bold=False,
        italic=False,
        transform=False,
        va="center",
        ha="center",
        fontsize=9,
    )
    ax.fill_between([1, 2], y1=-499.5, y2=-500.5, color="brown", alpha=0.5)
    fs.add_annotation(
        ax=ax,
        text="Delay interbed",
        xy=(1.5, -510.0),
        xytext=(1.6, -300),
        bold=False,
        italic=False,
        fontsize=9,
        ha="center",
        va="center",
        zorder=100,
        arrowprops=arrow_props,
    )
    mc.plot_grid(color="0.5", lw=0.5, zorder=100)

    ax.set_xlim(0, 3)
    ax.set_ylabel("Elevation, in meters")
    ax.set_xlabel("x-coordinate, in meters")
    fs.remove_edge_ticks(ax)

    plt.tight_layout()

    # save figure
    if config.plotSave:
        fpth = os.path.join("..", "figures",
                            "{}-grid{}".format(sim_name, config.figure_ext))
        if not silent:
            print("saving...'{}'".format(fpth))
        fig.savefig(fpth)
def plot_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)
Example #4
0
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_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_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
Example #7
0
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
def plot_grid(gwf, silent=True):
    sim_ws = os.path.join(ws, sim_name)

    # create lake array
    ilake = gwf.dis.idomain.array
    ilake[ilake == 0] = 100
    ilake[ilake == 1] = 0
    ilake[ilake == 100] = 1
    for k in range(nlay):
        for i in range(16, nrow):
            for j in range(ncol):
                if ilake[k, i, j] == 1:
                    ilake[k, i, j] = 2

    # get edges and centers of cells
    xedges, yedges = gwf.modelgrid.xyedges[0], gwf.modelgrid.xyedges[1]
    xcenters, ycenters = gwf.modelgrid.xycenters[0], gwf.modelgrid.xycenters[1]

    # create sfr network
    poly0 = [
        [xcenters[4], yedges[1]],
        [xcenters[4], ycenters[4]],
        [xcenters[7], ycenters[4]],
        [xcenters[7], yedges[6]],
    ]
    poly1 = [
        [xcenters[8], yedges[11]],
        [xcenters[8], yedges[13]],
        [xcenters[9], yedges[14]],
        [xcenters[9], yedges[16]],
    ]
    poly2 = [
        [xcenters[9], yedges[21]],
        [xcenters[9], ycenters[22]],
        [xedges[16], ycenters[22]],
    ]
    parts = [poly0, poly1, poly2]
    shape_pth = os.path.join(ws, sim_name, "sfr.shp")
    w = shp.Writer(target=shape_pth, shapeType=shp.POLYLINE)
    w.field("no", "C")
    w.line([poly0])
    w.record(["1"])
    w.line([poly1])
    w.record(["2"])
    w.line([poly2])
    w.record(["3"])
    w.close()
    sfr = shp.Reader(shape_pth)

    # load the observations
    fpth = os.path.join(ws, sim_name, "{}.lak.obs.csv".format(sim_name))
    lak_results = np.genfromtxt(fpth, delimiter=",", names=True)

    # create MODFLOW 6 head object
    file_name = gwf.oc.head_filerecord.get_data()[0][0]
    fpth = os.path.join(sim_ws, file_name)
    hobj = flopy.utils.HeadFile(fpth)

    # create MODFLOW 6 cell-by-cell budget object
    file_name = gwf.oc.budget_filerecord.get_data()[0][0]
    fpth = os.path.join(sim_ws, file_name)
    cobj = flopy.utils.CellBudgetFile(fpth, precision="double")

    kstpkper = hobj.get_kstpkper()

    head = hobj.get_data(kstpkper=kstpkper[0])
    spdis = cobj.get_data(text="DATA-SPDIS", kstpkper=kstpkper[0])

    # add lake stage to heads
    head[ilake == 1] = lak_results["LAKE1"][-1]
    head[ilake == 2] = lak_results["LAKE2"][-1]

    # observation locations
    p1 = (xcenters[3], ycenters[3])
    p2 = (xcenters[8], ycenters[13])
    p3 = (xcenters[13], ycenters[23])

    # lake text locations
    pl1 = (xcenters[8], ycenters[8])
    pl2 = (xcenters[8], ycenters[18])

    fs = USGSFigure(figure_type="map", verbose=False)
    fig = plt.figure(
        figsize=(4, 6.9),
        tight_layout=True,
    )
    plt.axis("off")

    nrows, ncols = 10, 1
    axes = [fig.add_subplot(nrows, ncols, (1, 8))]

    for idx, ax in enumerate(axes):
        ax.set_xlim(extents[:2])
        ax.set_ylim(extents[2:])
        ax.set_aspect("equal")

    # legend axis
    axes.append(fig.add_subplot(nrows, ncols, (9, 10)))

    # set limits for legend area
    ax = axes[-1]
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)

    # get rid of ticks and spines for legend area
    ax.axis("off")
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines["top"].set_color("none")
    ax.spines["bottom"].set_color("none")
    ax.spines["left"].set_color("none")
    ax.spines["right"].set_color("none")
    ax.patch.set_alpha(0.0)

    ax = axes[0]
    mm = flopy.plot.PlotMapView(gwf, ax=ax, extent=extents)
    mm.plot_bc("CHD", color="cyan")
    for shape in sfr.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        ax.plot(x, y, color="#3BB3D0", lw=1.5, zorder=1)
    mm.plot_inactive(color_noflow="#5DBB63")
    mm.plot_grid(lw=0.5, color="black")
    cv = mm.contour_array(
        head,
        levels=np.arange(120, 160, 5),
        linewidths=0.75,
        linestyles="-",
        colors="blue",
        masked_values=masked_values,
    )
    plt.clabel(cv, fmt="%1.0f")
    mm.plot_specific_discharge(spdis, normalize=True, color="0.75")
    ax.plot(p1[0], p1[1], marker="o", mfc="red", mec="black", ms=4)
    ax.plot(p2[0], p2[1], marker="o", mfc="red", mec="black", ms=4)
    ax.plot(p3[0], p3[1], marker="o", mfc="red", mec="black", ms=4)
    ax.set_xlabel("x-coordinate, in feet")
    ax.set_ylabel("y-coordinate, in feet")
    fs.add_text(
        ax,
        "A",
        x=p1[0] + 150,
        y=p1[1] + 150,
        transform=False,
        bold=False,
        color="red",
        ha="left",
        va="bottom",
    )
    fs.add_text(
        ax,
        "B",
        x=p2[0] + 150,
        y=p2[1] + 150,
        transform=False,
        bold=False,
        color="red",
        ha="left",
        va="bottom",
    )
    fs.add_text(
        ax,
        "C",
        x=p3[0] + 150,
        y=p3[1] + 150,
        transform=False,
        bold=False,
        color="red",
        ha="left",
        va="bottom",
    )
    fs.add_text(
        ax,
        "Lake 1",
        x=pl1[0],
        y=pl1[1],
        transform=False,
        italic=False,
        color="white",
        ha="center",
        va="center",
    )
    fs.add_text(
        ax,
        "Lake 2",
        x=pl2[0],
        y=pl2[1],
        transform=False,
        italic=False,
        color="white",
        ha="center",
        va="center",
    )
    fs.remove_edge_ticks(ax)

    # legend
    ax = axes[-1]
    ax.plot(
        -10000,
        -10000,
        lw=0,
        marker="s",
        ms=10,
        mfc="#5DBB63",
        mec="black",
        markeredgewidth=0.5,
        label="Lake boundary",
    )
    ax.plot(
        -10000,
        -10000,
        lw=0,
        marker="s",
        ms=10,
        mfc="cyan",
        mec="black",
        markeredgewidth=0.5,
        label="Constant-head boundary",
    )
    ax.plot(
        -10000,
        -10000,
        lw=1.5,
        color="#3BB3D0",
        label="Stream network",
    )
    ax.plot(
        -10000,
        -10000,
        lw=0,
        marker="o",
        ms=4,
        mfc="red",
        mec="black",
        markeredgewidth=0.5,
        label="Observation well",
    )
    ax.plot(
        -10000,
        -10000,
        lw=0.75,
        ls="-",
        color="blue",
        label=r"Head contour, $ft$",
    )
    ax.plot(
        -10000,
        -10000,
        lw=0,
        marker=u"$\u2192$",
        ms=10,
        mfc="0.75",
        mec="0.75",
        label="Normalized specific discharge",
    )
    fs.graph_legend(ax, loc="lower center", ncol=2)

    # save figure
    if config.plotSave:
        fpth = os.path.join(
            "..",
            "figures",
            "{}-grid{}".format(sim_name, config.figure_ext),
        )
        fig.savefig(fpth)

    return
Example #9
0
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)