%%javascript
IPython.OutputArea.prototype._should_scroll = function(lines) {
return false;
}
This tutorial is meant to introduce some animation in the 3D viewer in Ptyhon
import gstlearn as gl
import gstlearn.plot3D as gop
import plotly.graph_objects as go
import plotly.express as px
from dash import Dash, dcc, html, Input, Output, callback
We create a 3D grid. The number of cells is voluntarily limited in order to allow flexible rendering in this tutorial.
ndim = 3
gl.defineDefaultSpace(gl.ESpaceType.RN, ndim)
nx = 50
ny = 50
nz = 30
grid = gl.DbGrid.create(nx = [nx,ny,nz],dx = [1,1,0.2])
We create a 3D simulation filled with a non-conditional simulation (performed using the Turning Bands method). Here again the number of Turning Bands is voluntarily limited to improve the efficiency.
nbtuba= 200
model = gl.Model.createFromParam(gl.ECov.CUBIC,ranges = [20,30,2])
err = gl.simtub(None,grid,model,nbtuba=nbtuba)
Default values for the rendering of a fence diagram
ix = 12
iy = 3
iz = 25
In the next graphic, we display a Fence Diagram: one section along each main axis of the grid is displayed. Although the indices along X-axis and Y-axis are fixed (using the default values defined in the next paragraph), the index of the cell defining the horizontal plane is left variable.
In this first example, the user can define it using a slider.
app = Dash()
app.layout = html.Div([
dcc.Graph(id='Fence'),
dcc.Slider(min=0, max=nz-1, step=1, value=5, marks=None,
tooltip={"placement": "bottom", "always_visible": True}, id='IZ-slider')
])
@callback(
Output('Fence', 'figure'),
Input('IZ-slider', 'value')
)
def update_figure(value):
iz = value % nz
data = [gop.SliceOnDbGrid(grid,"Simu",0,ix),
gop.SliceOnDbGrid(grid,"Simu",1,iy),
gop.SliceOnDbGrid(grid,"Simu",2,iz)]
fig1 = go.Figure(data=data)
fig1.layout.title = f"Fence Diagram {ix} - {iy} - {value}"
fig1['layout']['uirevision'] = 'some-constant'
return fig1
app.run()
In the next graphic, the level of the horizontal plane which is visualized in the Fence Diagram varies automatically. It covers the whole range of the cells along the vertical axis: when overpassing the number of cells of the grid, it cycles back to 0.
app = Dash()
app.layout = html.Div([
dcc.Graph(id='Fence'),
dcc.Interval(id='Time-interval',
interval=1*1000, # in milliseconds
n_intervals=0)
])
@callback(
Output('Fence', 'figure'),
Input('Time-interval', 'n_intervals')
)
def update_metrics(value):
iz = value % nz
data = [gop.SliceOnDbGrid(grid,"Simu",0,ix),
gop.SliceOnDbGrid(grid,"Simu",1,iy),
gop.SliceOnDbGrid(grid,"Simu",2,iz)]
fig1 = go.Figure(data=data)
fig1.layout.title = f"Fence Diagram {ix} - {iy} - {value}"
fig1['layout']['uirevision'] = 'some-constant'
return fig1
app.run()