diff --git a/flopy/plot/crosssection.py b/flopy/plot/crosssection.py index e50ad5ed8..5ae25e518 100644 --- a/flopy/plot/crosssection.py +++ b/flopy/plot/crosssection.py @@ -51,6 +51,13 @@ class PlotCrossSection: minimum width of a grid cell polygon to be plotted. Cells with a cross-sectional width less than min_segment_length will be ignored and not included in the plot. Default is 1e-02. + view : str + view can be used to force the view of the cross section when a line is provided. + "auto" is default and mimics the long term behavior of flopy, which decides + on the view by taking the maximum of the x and y direction of the cross + sectional line. "x" forces the view to be plotted from the x direction + (bottom of the unrotated grid). and "y" forces the view to be plotted from the + y-direction "left" or "right" side of the unrotated grid. """ def __init__( @@ -62,7 +69,9 @@ def __init__( extent=None, geographic_coords=False, min_segment_length=1e-02, + view="auto", ): + view = view.lower() self.ax = ax self.geographic_coords = geographic_coords self.model = model @@ -159,7 +168,10 @@ def __init__( yp.append(v2) xp, yp = self.mg.get_local_coords(xp, yp) - if np.max(xp) - np.min(xp) > np.max(yp) - np.min(yp): + if (np.max(xp) - np.min(xp) > np.max(yp) - np.min(yp)) or view not in ( + "auto", + "y", + ): # this is x-projection and we should buffer x by small amount idx0 = np.argmax(xp) idx1 = np.argmin(xp) diff --git a/flopy/plot/plotutil.py b/flopy/plot/plotutil.py index f79b13321..23f6d00f3 100644 --- a/flopy/plot/plotutil.py +++ b/flopy/plot/plotutil.py @@ -1685,6 +1685,15 @@ def line_intersect_grid(ptsin, xgrid, ygrid): if t: vdict[cell] = t + # check if line vertex 0 or -1 should be included in the crosssection + ptschk = [ptsin[0], ptsin[-1]] + for cell, vrts in vdict.items(): + if len(vrts) == 1: + for pt in ptschk: + if np.min(xgrid[cell]) < pt[0] < np.max(xgrid[cell]): + if np.min(ygrid[cell]) < pt[1] < np.max(ygrid[cell]): + vdict[cell] = [vrts[0], tuple(pt)] + return vdict @staticmethod diff --git a/flopy/utils/rasters.py b/flopy/utils/rasters.py index c2c72a596..10489e308 100644 --- a/flopy/utils/rasters.py +++ b/flopy/utils/rasters.py @@ -81,7 +81,10 @@ def __init__( elif array.dtype in Raster.FLOAT64: dtype = "float64" elif array.dtype in Raster.INT8: - dtype = "int8" + if np.max(array) > 127: + dtype = "uint8" + else: + dtype = "int8" elif array.dtype in Raster.INT16: dtype = "int16" elif array.dtype in Raster.INT32: @@ -996,6 +999,7 @@ def plot(self, ax=None, contour=False, **kwargs): import_optional_dependency("rasterio") from rasterio.plot import show + band = kwargs.pop("band", None) # rasterio >= 1.5 defaults to adjusting data to [0, 1], which # can clash with user-supplied vmin/vmax. don't adjust unless # the caller explicitly asks for it @@ -1013,11 +1017,15 @@ def plot(self, ax=None, contour=False, **kwargs): if d1 is None: raise AssertionError("No plottable arrays found") - data = np.zeros((d0, d1, d2), dtype=float) - i = 0 - for _, arr in sorted(self.__arr_dict.items()): - data[i, :, :] = arr - i += 1 + if band is not None: + data = np.zeros((1, d1, d2), dtype=float) + data[0] = self.__arr_dict[band] + else: + data = np.zeros((d0, d1, d2), dtype=float) + i = 0 + for _, arr in sorted(self.__arr_dict.items()): + data[i, :, :] = arr + i += 1 data = np.ma.masked_where(data == self.nodatavals, data) ax = show(