Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:modflowpy/flopy into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mnfienen committed Jun 7, 2019
2 parents 5028382 + f0a7214 commit a459e79
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 32 deletions.
45 changes: 41 additions & 4 deletions autotest/t007_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,11 @@ def test_mt_modelgrid():
mt = flopy.mt3d.Mt3dms(modelname='test_mt', modflowmodel=ml,
model_ws=ml.model_ws, verbose=True)
btn = flopy.mt3d.Mt3dBtn(mt, icbund=ml.bas6.ibound.array)

# reload swt
swt = flopy.seawat.Seawat(modelname='test_swt', modflowmodel=ml,
mt3dmodel=mt, model_ws=ml.model_ws, verbose=True)

assert \
ml.modelgrid.xoffset == mt.modelgrid.xoffset == swt.modelgrid.xoffset
assert \
Expand Down Expand Up @@ -903,6 +903,42 @@ def check_vertices():
plt.close()


def test_tricontour_NaN():
from flopy.plot import PlotMapView
import numpy as np
from flopy.discretization import StructuredGrid

arr = np.random.rand(10, 10) * 100
arr[-1, :] = np.nan
delc = np.array([10] * 10, dtype=float)
delr = np.array([8] * 10, dtype=float)
top = np.ones((10, 10), dtype=float)
botm = np.ones((3, 10, 10), dtype=float)
botm[0] = 0.75
botm[1] = 0.5
botm[2] = 0.25
idomain = np.ones((3, 10, 10))
idomain[0, 0, :] = 0
vmin = np.nanmin(arr)
vmax = np.nanmax(arr)
levels = np.linspace(vmin, vmax, 7)

grid = StructuredGrid(delc=delc,
delr=delr,
top=top,
botm=botm,
idomain=idomain,
lenuni=1,
nlay=3, nrow=10, ncol=10)

pmv = PlotMapView(modelgrid=grid, layer=0)
contours = pmv.contour_array(a=arr)

for ix, lev in enumerate(contours.levels):
if not np.allclose(lev, levels[ix]):
raise AssertionError("TriContour NaN catch Failed")


def test_get_vertices():
from flopy.utils.reference import SpatialReference
from flopy.discretization import StructuredGrid
Expand Down Expand Up @@ -1191,7 +1227,7 @@ def test_export_array_contours():
# build_sfr_netcdf()
# test_mg()
# test_mbase_modelgrid()
test_mt_modelgrid()
# test_mt_modelgrid()
# test_rotation()
# test_model_dot_plot()
# test_vertex_model_dot_plot()
Expand All @@ -1212,5 +1248,6 @@ def test_export_array_contours():
#test_wkt_parse()
#test_get_rc_from_node_coordinates()
# test_export_array()
# test_export_array_contours()
test_export_array_contours()
test_tricontour_NaN()
pass
62 changes: 50 additions & 12 deletions flopy/plot/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,13 @@ def plot_array(self, a, masked_values=None, **kwargs):
raise Exception('Array must be of dimension 1, 2, or 3')

elif self.mg.grid_type == "vertex":
if a.ndim == 2:
if a.ndim == 3:
if a.shape[0] == 1:
a = np.squeeze(a, axis=1)
plotarray = a[self.layer, :]
else:
raise Exception("Array must be of dimension 1 or 2")
elif a.ndim == 2:
plotarray = a[self.layer, :]
elif a.ndim == 1:
plotarray = a
Expand Down Expand Up @@ -215,6 +221,7 @@ def contour_array(self, a, masked_values=None, **kwargs):
err_msg = "Matplotlib must be updated to use contour_array"
raise ImportError(err_msg)

a = np.copy(a)
if not isinstance(a, np.ndarray):
a = np.array(a)

Expand All @@ -232,7 +239,13 @@ def contour_array(self, a, masked_values=None, **kwargs):
raise Exception('Array must be of dimension 1, 2 or 3')

elif self.mg.grid_type == "vertex":
if a.ndim == 2:
if a.ndim == 3:
if a.shape[0] == 1:
a = np.squeeze(a, axis=1)
plotarray = a[self.layer, :]
else:
raise Exception("Array must be of dimension 1 or 2")
elif a.ndim == 2:
plotarray = a[self.layer, :]
elif a.ndim == 1:
plotarray = a
Expand All @@ -242,9 +255,39 @@ def contour_array(self, a, masked_values=None, **kwargs):
else:
plotarray = a

# work around for tri-contour ignore vmin & vmax
# necessary block for tri-contour NaN issue
if "levels" not in kwargs:
if "vmin" not in kwargs:
vmin = np.nanmin(plotarray)
else:
vmin = kwargs.pop("vmin")
if "vmax" not in kwargs:
vmax = np.nanmax(plotarray)
else:
vmax = kwargs.pop('vmax')

levels = np.linspace(vmin, vmax, 7)
kwargs['levels'] = levels

# workaround for tri-contour nan issue
# use -2**31 to allow for 32 bit int arrays
plotarray[np.isnan(plotarray)] = -2**31
if masked_values is None:
masked_values = [-2**31]
else:
masked_values = list(masked_values)
if -2**31 not in masked_values:
masked_values.append(-2**31)

ismasked = None
if masked_values is not None:
for mval in masked_values:
plotarray = np.ma.masked_equal(plotarray, mval)
if ismasked is None:
ismasked = np.equal(plotarray, mval)
else:
t = np.equal(plotarray, mval)
ismasked += t

if 'ax' in kwargs:
ax = kwargs.pop('ax')
Expand Down Expand Up @@ -276,16 +319,11 @@ def contour_array(self, a, masked_values=None, **kwargs):
ycentergrid = ycentergrid.flatten()
triang = tri.Triangulation(xcentergrid, ycentergrid)

mask = None
try:
amask = plotarray.mask
mask = [False for i in range(triang.triangles.shape[0])]
for ipos, (n0, n1, n2) in enumerate(triang.triangles):
if amask[n0] or amask[n1] or amask[n2]:
mask[ipos] = True
if ismasked is not None:
ismasked = ismasked.flatten()
mask = np.any(np.where(ismasked[triang.triangles],
True, False), axis=1)
triang.set_mask(mask)
except (AttributeError, IndexError):
pass

contour_set = ax.tricontour(triang, plotarray, **kwargs)

Expand Down
50 changes: 50 additions & 0 deletions flopy/plot/plotutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,56 @@ def line_intersect_grid(ptsin, xgrid, ygrid):

return vdict

@staticmethod
def irregular_shape_patch(xverts, yverts):
"""
Patch for vertex cross section plotting when
we have an irregular shape type throughout the
model grid or multiple shape types.
Parameters
----------
xverts : list
xvertices
yverts : list
yvertices
Returns
-------
xverts, yverts as np.ndarray
"""
max_verts = 0

for xv in xverts:
if len(xv) > max_verts:
max_verts = len(xv)

for yv in yverts:
if len(yv) > max_verts:
max_verts = len(yv)

adj_xverts = []
for xv in xverts:
if len(xv) < max_verts:
n = max_verts - len(xv)
adj_xverts.append(xv + [xv[-1]] * n)
else:
adj_xverts.append(xv)

adj_yverts = []
for yv in yverts:
if len(yv) < max_verts:
n = max_verts - len(yv)
adj_yverts.append(yv + [yv[-1]] * n)
else:
adj_yverts.append(yv)

xverts = np.array(adj_xverts)
yverts = np.array(adj_yverts)

return xverts, yverts

@staticmethod
def arctan2(verts):
"""
Expand Down
64 changes: 50 additions & 14 deletions flopy/plot/vcrosssection.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,22 @@ def __init__(self, ax=None, model=None, modelgrid=None,
self.mg.xoffset, self.mg.yoffset,
self.mg.angrot_radians, inverse=True)

self.xvertices, self.yvertices = \
geometry.transform(self.mg.xvertices,
self.mg.yvertices,
self.mg.xoffset, self.mg.yoffset,
self.mg.angrot_radians, inverse=True)
try:
self.xvertices, self.yvertices = \
geometry.transform(self.mg.xvertices,
self.mg.yvertices,
self.mg.xoffset, self.mg.yoffset,
self.mg.angrot_radians, inverse=True)
except ValueError:
# irregular shapes in vertex grid ie. squares and triangles
xverts, yverts = plotutil.UnstructuredPlotUtilities.\
irregular_shape_patch(self.mg.xvertices, self.mg.yvertices)

self.xvertices, self.yvertices = \
geometry.transform(xverts, yverts,
self.mg.xoffset,
self.mg.yoffset,
self.mg.angrot_radians, inverse=True)

pts = [(xt, yt) for xt, yt in zip(xp, yp)]
self.pts = np.array(pts)
Expand Down Expand Up @@ -430,9 +441,38 @@ def contour_array(self, a, masked_values=None, head=None, **kwargs):
plotarray = np.array([a[cell] for cell
in sorted(self.projpts)])

# work around for tri-contour ignore vmin & vmax
# necessary for the tri-contour NaN issue fix
if "levels" not in kwargs:
if "vmin" not in kwargs:
vmin = np.nanmin(plotarray)
else:
vmin = kwargs.pop("vmin")
if "vmax" not in kwargs:
vmax = np.nanmax(plotarray)
else:
vmax = kwargs.pop('vmax')

levels = np.linspace(vmin, vmax, 7)
kwargs['levels'] = levels

# workaround for tri-contour nan issue
plotarray[np.isnan(plotarray)] = -2**31
if masked_values is None:
masked_values = [-2**31]
else:
masked_values = list(masked_values)
if -2**31 not in masked_values:
masked_values.append(-2**31)

ismasked = None
if masked_values is not None:
for mval in masked_values:
plotarray = np.ma.masked_equal(plotarray, mval)
if ismasked is None:
ismasked = np.equal(plotarray, mval)
else:
t = np.equal(plotarray, mval)
ismasked += t

if isinstance(head, np.ndarray):
zcenters = self.set_zcentergrid(np.ravel(head))
Expand All @@ -457,15 +497,11 @@ def contour_array(self, a, masked_values=None, head=None, **kwargs):

triang = tri.Triangulation(xcenters, zcenters)

try:
amask = plotarray.mask
mask = [False for _ in range(triang.triangles.shape[0])]
for ipos, (n0, n1, n2) in enumerate(triang.triangles):
if amask[n0] or amask[n1] or amask[n2]:
mask[ipos] = True
if ismasked is not None:
ismasked = ismasked.flatten()
mask = np.any(np.where(ismasked[triang.triangles],
True, False), axis=1)
triang.set_mask(mask)
except (AttributeError, IndexError):
pass

contour_set = ax.tricontour(triang, plotarray, **kwargs)

Expand Down
4 changes: 2 additions & 2 deletions flopy/utils/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,9 @@ def transform(x, y, xoff, yoff, angrot_radians,
"""
if isinstance(x, list):
x = np.array(x)
x = np.array(x, dtype=float)
if isinstance(y, list):
y = np.array(y)
y = np.array(y, dtype=float)

if not np.isscalar(x):
x, y = x.copy(), y.copy()
Expand Down

0 comments on commit a459e79

Please sign in to comment.