Interactive MODFLOW MT3D transport model visualization with Flopy, Ipywidgets and Voila - Tutorial
/Representation and analysis of flow and transport results is a challenge for groundwater modelers. Aspects such as speed, compatibility, data format and visualization options are key in the 2D/3D representation of head and concentration on model cells. Under the Jupyterlab framework new tools have been developed that can be useful to represent model results on a user friendly way.
This time we have done a tutorial for the interactive representation of a contaminant plume in Jupyterlab; modeling was done with Modflow Nwt and Mt3d, representation was done with Matplolib, Ipywidgets and Voila.
You have two ways to run this code:
From the Hakuchik image for Docker: docker run -it -p 8888:8888 hatarilabs/hakuchik:74a2c9c18727
Using Anaconda with all the installed libraries
Files and scripts can be downloaded with:
git clone https://github.com/SaulMontoya/interactiveModflowTransportVisualization.git
Animation
Tutorial
Code
This is the complete Python code:
import flopy, os
import numpy as np
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
#get nam list
namList = [x[:-4] for x in os.listdir('../model') if x[-4:]=='.nam']
#get ucn list
ucnList = [x[:-4] for x in os.listdir('../model') if x[-4:]=='.ucn']
#nam dropdown widget
namDrop = widgets.Dropdown(
options=namList,
value=namList[0],
description='Nam file:',
disabled=False,
layout=widgets.Layout(width='20%')
)
#nam dropdown widget
ucnDrop = widgets.Dropdown(
options=ucnList,
value=ucnList[0],
description='Conc file:',
disabled=False,
layout=widgets.Layout(width='20%')
)
#times dropdown widget
timeBot = widgets.Button(
description='Show times:',
disabled=False,
button_style='success', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Show available times',
)
#times dropdown widget
timeDrop = widgets.Dropdown(
options=[0],
value=0, #ucnList[0],
description='Times:',
disabled=False,
layout=widgets.Layout(width='20%')
)
#plot widget
plotBot = widgets.Button(
description='Plot conc.',
disabled=True,
button_style='success', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Plot concentrations at specified layer',
)
#plot function
def showLayConc(namFile,ucnFile,timeDrop):
with out:
out.clear_output()
m = flopy.modflow.mf.Modflow.load('../model/'+namFile+'.nam',version='mfnwt')
fig, ax = plt.subplots(figsize=(12,8))
#modelmap = m.modelgrid.plot(ax=ax)
modelmap = flopy.plot.PlotMapView(m,ax=ax)
ucnFile = flopy.utils.binaryfile.UcnFile('../model/'+ucnFile+'.ucn')
concArray = ucnFile.get_data(totim=timeDrop)
concArray[concArray == -1.e+30] = np.nan
modelmap.plot_array(concArray)
plt.show()
def listTimes(ucnFile):
ucnFile = flopy.utils.binaryfile.UcnFile('../model/'+ucnFile+'.ucn')
return ucnFile.get_times()
#on click function
def plotButtonClicked(b):
showLayConc(namDrop.value,ucnDrop.value,timeDrop.value)
#plotBot.disabled = True
#on click function
def timesButtonClicked(b):
timeDrop.options = listTimes(ucnDrop.value)
plotBot.disabled = False
timeBot.disabled = True
timeBot.button_style = ''
plotBot.on_click(plotButtonClicked)
timeBot.on_click(timesButtonClicked)
display(widgets.HBox([namDrop, ucnDrop, timeBot, timeDrop, plotBot]))
out = widgets.Output()
display(out)