Utilizzo di Plotly 3D Surface Plots per visualizzare le superfici geologiche.

'Using Plotly 3D Surface Plots to visualize geological surfaces.'

Visualizzazione del sottosuolo utilizzando le librerie di visualizzazione dei dati di Python

Grafico a superficie 3D della formazione di Hugin. Immagine dell'autore.

All’interno della geoscienza, è essenziale avere una comprensione completa delle superfici geologiche presenti nel sottosuolo. Conoscendo l’esatta posizione della formazione e la sua geometria, diventa più facile identificare nuovi potenziali obiettivi per l’esplorazione di petrolio e gas, così come potenziali posizioni di cattura e stoccaggio di carbonio. Ci sono una varietà di metodi che possiamo utilizzare per raffinare queste superfici che vanno dai dati sismici ai dati di formazione ottenuti dai registri di pozzo. Più spesso, queste tecniche vengono utilizzate in combinazione tra loro per raffinare la superficie finale.

Questo articolo continua dai miei articoli precedenti, che si sono concentrati sul processo di estrapolazione delle misurazioni dei registri di pozzo in una regione per comprendere e visualizzare le variazioni geospaziali. In questo articolo, vedremo come possiamo creare superfici 3D utilizzando grafici interattivi di Plotly.

Poiché la modellizzazione delle superfici geologiche è un processo complesso e spesso prevede molteplici iterazioni e raffinamenti, questo articolo dimostra un esempio molto semplice di come possiamo visualizzare questi dati con Python.

Per vedere come possiamo utilizzare Plotly per visualizzare la nostra formazione geologica in cima attraverso un’area, utilizzeremo due set di dati.

Il primo set di dati è derivato da 28 intersezioni con la formazione derivata dalle scelte del pozzo, che vengono utilizzate come input per la kriging per produrre una superficie a bassa risoluzione. In contrasto, il secondo set di dati è derivato dai dati sismici interpretati, fornendo una superficie a risoluzione molto più alta.

Entrambi i set di dati provengono dall’insieme di dati Equinor Volve. I dettagli sono nella parte inferiore di questo articolo.

Puoi anche controllare i seguenti articoli all’interno di questa mini-serie ai link sottostanti:

  • Plotly e Python: Creazione di heatmap interattive per dati petrofisici e geologici
  • Utilizzo di pykrige e matplotlib per la visualizzazione spaziale delle variazioni geologiche
  • Visualizzazione dei percorsi dei pozzetti su grafici a linee 3D con Plotly Express

Importazione di librerie e dati

Prima di tentare di lavorare con i dati, dobbiamo prima importare le librerie di cui avremo bisogno. Questi sono:

  • pandas — per leggere i nostri dati, che sono in formato csv
  • matplotlib per creare la nostra visualizzazione
  • pykrige per effettuare la kriging
  • numpy per alcuni calcoli numerici
  • plotly.graph_objects per visualizzare superfici in 3D
import pandas as pdimport matplotlib.pyplot as pltimport plotly.graph_objects as gofrom pykrige import OrdinaryKrigingimport numpy as np

Successivamente, possiamo caricare i dati utilizzando pd.read_csv().

Poiché questi dati contengono informazioni sulle superfici geologiche di tutti i pozzi all’interno del campo di Volve, possiamo utilizzare query() per estrarre i dati per la formazione di cui abbiamo bisogno. In questo caso, guarderemo alla formazione di Hugin.

df = pd.read_csv('Data/Volve/Well_picks_Volve_v1 copy.csv')df_hugin = df.query('SURFACE == "Hugin Fm. VOLVE Top"')df_hugin

Quando eseguiamo il codice sopra, otteniamo la seguente tabella. Potresti notare che alcuni pozzi hanno incontrato la formazione di Hugin più di una volta. Questo è probabilmente dovuto ai pozzi che penetrano la formazione più di una volta a causa della geometria del pozzo o della formazione.

Dataframe di Pandas contenente informazioni sulle scelte di formazione per la formazione di Hugin nel campo di Volve. Immagine dell'autore.

Estrapolazione di TVDSS per generare la superficie geologica

In precedenza, mi sono concentrato su come possiamo utilizzare un processo noto come kriging per “riempire i vuoti” tra i punti di misurazione. Non tratteremo i dettagli di questo processo in questo articolo; tuttavia, puoi controllare questo articolo per maggiori informazioni.

Dopo che i nostri dati sono stati caricati, possiamo eseguire il processo di kriging chiamando il metodo OrdinaryKriging di pykrige.

All’interno di questa chiamata, passiamo i nostri dati x e y che rappresentano la posizione Est e Nord dove il pozzo ha incontrato la formazione all’interno del sottosuolo.

Poiché vogliamo generare una superficie della Formazione Hugin, dobbiamo utilizzare la misura TVDSS – True Vertical Depth Subsea. Ciò fornisce una vera riflessione di quanto in profondità è la superficie sotto il dato selezionato.

OK = OrdinaryKriging(x=df_hugin['Easting'],                       y=df_hugin['Northing'],                       z=df_hugin['TVDSS'],                      variogram_model='linear',                      verbose=True, enable_plotting=True)
Risultati del Kriging ordinario per la Formazione Hugin. Immagine dell'autore.

Una volta che il modello è stato generato, possiamo applicarlo a due matrici che coprono l’intera gamma di punti di perforazione del pozzo.

Ciò ci consente di generare una griglia di valori che vengono quindi passati all’oggetto OrdinaryKriging che abbiamo generato in precedenza.

gridx = np.arange(433986, 438607, 50, dtype='float64')gridy = np.arange(6477539, 6479393, 50,dtype='float64')zstar, ss = OK.execute('grid', gridx, gridy)

Per finire, possiamo generare una semplice vista della superficie 2D utilizzando il metodo imshow di matplotlib.

fig, ax = plt.subplots(figsize=(15,5))# Crea un'immagine 2D dei dati in 'zstar'# Il parametro 'extent' imposta i limiti dell'immagine nelle coordinate dei dati# Il parametro 'origin' imposta la parte dell'immagine che corrisponde all'origine degli assiimage = ax.imshow(zstar, extent=(433986, 438607, 6477539, 6479393),                   origin='lower')# Imposta le etichette per l'asse x e l'asse yax.set_xlabel('Posizione X (m)', fontsize=14, fontweight='bold')ax.set_ylabel('Posizione Y (m)', fontsize=14, fontweight='bold')# Aggiungi le linee di contornocontours = ax.contour(gridx, gridy, zstar, colors='black')colorbar = fig.colorbar(image)colorbar.set_label('DTC (us/ft)', fontsize=14, fontweight='bold')# Mostra il graficoplt.show()
Mappa di superficie e contorno 2D della Formazione Hugin dopo l'applicazione del kriging. Immagine dell'autore.

Creazione di un semplice grafico di superficie 3D con Plotly

Per convertire la nostra superficie 2D in 3D, dobbiamo usare Plotly. Potremmo usare matplotlib per farlo; tuttavia, dalla mia esperienza, è più facile, più fluido e più interattivo generare le visualizzazioni 3D con Plotly.

Nel codice qui sotto, prima creiamo la nostra griglia di coordinate. Per farlo, usiamo la funzione linspace di numpy. Questa funzione creerà un insieme di numeri equidistanti su un intervallo specificato. Per il nostro dataset e l’esempio, l’intervallo si estende dal minimo al massimo di xgrid_extent e ygrid_extent.

Il numero totale di valori utilizzati all’interno di questo intervallo sarà equivalente al numero di elementi x e y presenti nella griglia zstar che abbiamo creato sopra.

Dopo aver formato la nostra griglia, chiamiamo la libreria Plotly.

Innanzitutto, creiamo il nostro oggetto figura e poi usiamo fig.add_trace per aggiungere il nostro grafico a superficie 3D alla figura.

Dopo averlo aggiunto, dobbiamo regolare il layout del nostro grafico in modo da avere etichette degli assi, una larghezza e un’altezza definite e un po’ di spazio vuoto.

xgrid_extent = [433986, 438607]ygrid_extent = [6477539, 6479393]x = np.linspace(xgrid_extent[0], xgrid_extent[1], zstar.shape[1])y = np.linspace(ygrid_extent[0], ygrid_extent[1], zstar.shape[0])fig = go.Figure()fig.add_trace(go.Surface(z=zstar, x=x, y=y))fig.update_layout(scene = dict(                    xaxis_title='Posizione X',                    yaxis_title='Posizione Y',                    zaxis_title='Profondità'),                  width=1000,                  height=800,                  margin=dict(r=20, l=10, b=10, t=10))fig.show()

Quando eseguiamo il codice sopra, otteniamo il seguente grafico interattivo che mostra la superficie geologica della formazione di Hugin basata sui multipli incontri dai pozzi di perforazione.

Grafico a superficie 3D della formazione di Hugin generato con Plotly. Immagine dell'autore.

Visualizzazione di una superficie completamente interpretata con Plotly

Il dataset di Volve ha diverse superfici completamente interpretate che sono state generate dalle interpretazioni geologiche, incluse le informazioni sismiche.

Questi dati contengono le posizioni x e y dei punti di dati in tutto il campo, nonché i nostri dati TVDSS (z).

I dati forniti sul portale dati di Volve sono in formato .dat, tuttavia, con un po’ di manipolazione all’interno di un editor di testo, possono essere facilmente convertiti in un file CSV e caricati utilizzando pandas.

hugin_formation_surface = pd.read_csv('Data/Volve/Hugin_Fm_Top+ST10010ZC11_Near_190314_adj2_2760_EasyDC+STAT+DEPTH.csv')
Posizioni X, Y e Z della formazione di Hugin. Immagine dell'autore.

Una volta caricati i dati, possiamo semplificare le cose estrarre i dati x, y e z in variabili.

x = hugin_formation_surface['x']y = hugin_formation_surface['y']z = hugin_formation_surface['z']

Dobbiamo poi creare una griglia regolarmente spaziata tra le nostre posizioni minime e massime all’interno delle posizioni di dati x e y. Ciò può essere fatto utilizzando meshgrid di numpy.

xi = np.linspace(x.min(), x.max(), 100)yi = np.linspace(y.min(), y.max(), 100)xi, yi = np.meshgrid(xi, yi)

Ci sono diversi modi per interpolare tra una serie di punti dati. Il metodo scelto dipenderà dalla forma dei tuoi dati (punti di dati campionati regolarmente vs campionati irregolarmente), dalla dimensione dei dati e dalla potenza di calcolo.

Se abbiamo un grande dataset come quello qui, sarà molto più costoso dal punto di vista computazionale con alcuni dei metodi come la funzione base radiale.

Per questo esempio, useremo il metodo LinearNDInterpolator all’interno di scipy per costruire il nostro modello e quindi applicarlo alla nostra variabile z (TVDSS).

Per poter interpolare tra i punti, dobbiamo ridimensionare xi, yi in array 1D per l’interpolazione, poiché LinearNDInterpolator si aspetta un array 1D.

xir = xi.ravel()yir = yi.ravel()interp = LinearNDInterpolator((x, y), z)zi = interp(xir, yir)

Una volta che ciò è stato calcolato, possiamo passare alla creazione della nostra Superficie 3D con Plotly Graph Objects.

fig = go.Figure()fig.add_trace(go.Surface(z=zi, x=xi, y=yi, colorscale='Viridis'))fig.update_layout(scene = dict(                    xaxis_title='Easting (m)',                    yaxis_title='Northing (m)',                    zaxis_title='Profondità',                    zaxis=dict(autorange='reversed')),                  width=1000,                  height=800,                  margin=dict(r=20, l=10, b=10, t=10))fig.update_traces(contours_z=dict(show=True,                                   usecolormap=True,                                   project_z=True,                                  highlightcolor="white"))fig.show()

Quando eseguiamo il codice sopra, otteniamo il seguente grafico di superficie 3D della formazione di Hugin.

Superficie geologica interpretata completamente della formazione di Hugin. Immagine dell'autore.

Quando confrontiamo questo grafico con quello generato dalle misurazioni dei pozzi, possiamo sicuramente vedere somiglianze nella forma generale con la valle al centro. Tuttavia, la superficie derivata dal sismico fornisce molto maggiore dettaglio rispetto a quella derivata dai dati dei pozzi.

Confronto della superficie della formazione di Hugin generata da misurazioni di pochi log dei pozzi (a sinistra) con una superficie generata dai dati sismici (a destra). Immagine dell'autore.

Sommario

In questo breve tutorial, abbiamo visto come utilizzare il grafico di superficie 3D di Plotly per generare una visualizzazione interattiva 3D di una superficie geologica. Con i dati dei log dei pozzi, possiamo generare una superficie 3D dal look molto basilare. Ciò è dovuto al fatto che le misurazioni sono limitate ai punti in cui i pozzi hanno intersecato la formazione di Hugin, il che significa che otteniamo una superficie a bassa risoluzione.

Al contrario, possiamo generare un’immagine molto più realistica della formazione se disponiamo di punti di misurazione più dettagliati, come gli orizzonti derivati dal sismico.

Entrambi i metodi sono ugualmente validi, tuttavia, è necessario tenere a mente che quando si estrapolano i dati dei log dei pozzi, potremmo non essere in grado di generare un quadro completo di quella formazione in tutta l’area.

Dataset utilizzato

I dati utilizzati in questo tutorial sono un sottoinsieme del dataset Volve rilasciato da Equinor nel 2018. Tutti i dettagli del dataset, inclusa la licenza, possono essere trovati al seguente link

Volve field data set

Equinor ha rilasciato un set completo di dati dal campo Volve, 2008-2016. Clicca qui per scaricare per studio, ricerca…

www.equinor.com

La licenza dei dati di Volve si basa sulla licenza CC BY 4.0. Tutti i dettagli dell’accordo di licenza possono essere trovati qui:

https://cdn.sanity.io/files/h61q9gi9/global/de6532f6134b9a953f6c41bac47a0c055a3712d3.pdf?equinor-hrs-terms-and-conditions-for-licence-to-data-volve.pdf

Grazie per aver letto. Prima di andare via, dovresti sicuramente iscriverti al mio contenuto e ricevere i miei articoli nella tua casella di posta. Puoi farlo qui!

In secondo luogo, puoi vivere l’esperienza completa di Nisoo e sostenere migliaia di altri scrittori e me iscrivendoti a una membership. Costa solo $5 al mese e hai accesso completo a tutti i fantastici articoli di Nisoo, nonché la possibilità di guadagnare con la tua scrittura.

Se ti iscrivi utilizzando il mio link, mi supporterai direttamente con una parte della tua quota e non ti costerà di più. Se lo fai, grazie mille per il tuo supporto.