flopy for working with shapefilesincluding:
recarray2shp convience function for writing a numpy record array to a shapefileshp2recarray convience function for quickly reading a shapefile into a numpy recarrayutils.geometry classes for writing shapefiles of model input/output. For example, quickly writing a shapefile of model cells with errors identified by the checkerepsgRef class works for retrieving projection file information (WKT text) from spatialreference.org, and caching that information locally for when an internet connection isn't availableepsgRef if it becomes corruptedPoint and LineString classes can be used to quickly plot pathlines and endpoints from MODPATH (these are also used by the PathlineFile and EndpointFile classes to write shapefiles of this output)
In [1]:
    
%matplotlib inline
try:
    from importlib import reload # python3
except:
    pass # python2 (reload in default namespace)
import sys
import shutil
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import flopy
from flopy.utils.geometry import Polygon, LineString, Point
from flopy.utils.reference import SpatialReference
from flopy.export.shapefile_utils import recarray2shp, shp2recarray
from flopy.utils.modpathfile import PathlineFile, EndpointFile
from flopy.utils.reference import epsgRef
ep = epsgRef()
ep.reset()
print(sys.version)
print('numpy version: {}'.format(np.__version__))
print('matplotlib version: {}'.format(mpl.__version__))
print('flopy version: {}'.format(flopy.__version__))
    
    
In [2]:
    
m = flopy.modflow.Modflow('toy_model', model_ws='temp')
botm = np.zeros((2, 10, 10))
botm[0, :, :] = 1.5
botm[1, 5, 5] = 4 # negative layer thickness!
botm[1, 6, 6] = 4
dis = flopy.modflow.ModflowDis(nrow=10, ncol=10, 
                               nlay=2, delr=100, delc=100,
                               top=3, botm=botm, model=m)
    
In [3]:
    
m.sr = SpatialReference(delr=m.dis.delr * .3048, delc=m.dis.delc * .3048, xul=600000, yul=5170000, 
                        proj4_str='EPSG:26715', rotation=45)
    
    
In [4]:
    
chk = dis.check()
chk.summary_array
    
    
    Out[4]:
In [5]:
    
get_vertices = m.sr.get_vertices # function to get the referenced vertices for a model cell
geoms = [Polygon(get_vertices(i, j)) for i, j in chk.summary_array[['i', 'j']]]
    
In [6]:
    
geoms[0].type
    
    Out[6]:
In [7]:
    
geoms[0].exterior
    
    Out[7]:
In [8]:
    
geoms[0].bounds
    
    Out[8]:
In [9]:
    
geoms[0].plot() # this feature requires descartes
    
    
In [10]:
    
recarray2shp(chk.summary_array, geoms, 'temp/test.shp', epsg=26715)
    
    
In [11]:
    
shutil.copy('temp/test.prj', 'temp/26715.prj')
recarray2shp(chk.summary_array, geoms, 'temp/test.shp', prj='temp/26715.prj')
    
    
In [12]:
    
ra = shp2recarray('temp/test.shp')
ra
    
    Out[12]:
In [13]:
    
ra.geometry[0].plot()
    
    
requests epsgref.py is created in the site-packages folder  prj 
In [14]:
    
import epsgref
reload(epsgref)
from epsgref import prj
prj
    
    Out[14]:
In [15]:
    
from flopy.utils.reference import getprj, epsgRef
    
In [16]:
    
getprj(4326)
    
    Out[16]:
In [17]:
    
reload(epsgref)
from epsgref import prj
for k, v in prj.items():
    print('{}:\n{}\n'.format(k, v))
    
    
In [18]:
    
ep = epsgRef()
    
In [19]:
    
ep.add(9999, 'junk')
    
In [20]:
    
epsgRef.show()
    
    
In [21]:
    
ep.remove(9999)
epsgRef.show()
    
    
In [22]:
    
ep.reset()
    
    
In [23]:
    
reload(epsgref)
from epsgref import prj
prj
    
    Out[23]:
In [24]:
    
len(prj.keys())
    
    Out[24]:
In [25]:
    
pthfile = PathlineFile('../data/mp6/EXAMPLE-3.pathline')
pthdata = pthfile._data.view(np.recarray)
    
In [26]:
    
length_mult = 1. # multiplier to convert coordinates from model to real world
rot = 0 # grid rotation
particles = np.unique(pthdata.particleid)
geoms = []
for pid in particles:
    ra = pthdata[pthdata.particleid == pid]
    x, y = SpatialReference.rotate(ra.x * length_mult,
                                   ra.y * length_mult,
                                   theta=rot)
    z = ra.z
    geoms.append(LineString(list(zip(x, y, z))))
    
In [27]:
    
geoms[0]
    
    Out[27]:
In [28]:
    
geoms[0].plot()
    
    
In [29]:
    
fig, ax = plt.subplots()
for g in geoms:
    g.plot(ax=ax)
ax.autoscale()
ax.set_aspect(1)
    
    
In [30]:
    
eptfile = EndpointFile('../data/mp6/EXAMPLE-3.endpoint')
eptdata = eptfile.get_alldata()
    
In [31]:
    
x, y = SpatialReference.rotate(eptdata['x0'] * length_mult,
                               eptdata['y0'] * length_mult,
                               theta=rot)
z = eptdata['z0']
geoms = [Point(x[i], y[i], z[i]) for i in range(len(eptdata))]
    
In [32]:
    
fig, ax = plt.subplots()
for g in geoms:
    g.plot(ax=ax)
ax.autoscale()
ax.set_aspect(2e-6)
    
    
In [ ]: