Plotly e Python Creazione di mappe di calore interattive per dati petrofisici e geologici

Creating interactive heat maps for petrophysical and geological data using Plotly and Python.

Visualizzazione delle variazioni geospaziali nelle misurazioni dei registri di pozzo all’interno del sottosuolo

Mappa di calore Plotly utilizzata per esplorare la variazione geospaziale delle misurazioni dei registri di pozzo attraverso la piattaforma continentale norvegese. Immagine dell'autore.

L’interpretazione del sottosuolo richiede la comprensione di come i dati geologici e petrofisici variano in una regione. Ciò comporta spesso la gestione di misurazioni dei registri di pozzo e proprietà interpretate sparse nell’area, il che porta alla sfida di stimare i valori tra queste misurazioni.

Un modo per stimare i valori (o riempire i vuoti) è utilizzando un metodo geostatistico chiamato kriging. Questo metodo stima ed estrapola i dati tra le misurazioni osservate e predice i valori in posizioni non misurate.

Nel mio articolo precedente, ci siamo concentrati sull’utilizzo di pykrige e matplotlib per mappare e visualizzare la variazione geologica attraverso la piattaforma continentale norvegese. Questo articolo porterà quella visualizzazione oltre e renderà quei grafici interattivi.

Utilizzo di pykrige e matplotlib per la visualizzazione spaziale delle variazioni geologiche

Esplorazione della variazione geologica spaziale dalle misurazioni dei registri di pozzo

towardsdatascience.com

Breve ripasso sull’utilizzo di Pykrige

Prima di utilizzare Plotly, faremo un breve ripasso del codice utilizzato nell’articolo precedente in modo che tu sia al corrente del processo.

Il primo passo è importare le librerie che ci servono. In questo caso, abbiamo bisogno di pandas per caricare i nostri dati csv, pykrige per eseguire l’interpolazione tra i punti dati e numpy per eseguire alcune operazioni matematiche.

import pandas as pdfrom pykrige import OrdinaryKrigingimport numpy as npdf = pd.read_csv('Data/Xeek Force 2020/Xeek_2020_Balder_DTC_AVG.csv')

Una volta caricati i dati, possiamo eseguire il processo di kriging chiamando il metodo OrdinaryKriging di pykrige.

In questa chiamata, passiamo i nostri dati x e y, rappresentando la latitudine e la longitudine dei nostri dati. Dobbiamo anche passare la variabile che vogliamo estrapolare. In questo caso, stiamo utilizzando il valore medio della compressione acustica (DTC) per la formazione di Balder.

Una volta generato il modello, possiamo applicarlo a intervalli di latitudine e longitudine personalizzati che coprono le posizioni dei pozzi.

OK = OrdinaryKriging(x=df['LON'],                       y=df['LAT'],                       z=df['DTC_MEAN'],                      variogram_model='exponential',                      verbose=True, enable_plotting=True,                      coordinates_type='geographic')grid_lat = np.arange(57.5, 62, 0.01, dtype='float64')grid_long = np.arange(1.5, 4.5, 0.01,dtype='float64')zstar, ss = OK.execute('grid', grid_long, grid_lat)zstar

Poi prendiamo i nostri due array posizionali, grid_lat e grid_long e i nostri dati a griglia e li passiamo in un grafico imshow di matplotlib. Ciò genererà un grafico simile a quello sotto.

Grafico imshow di Matplotlib dei dati che sono stati eseguiti attraverso Ordinary Kriging utilizzando pykrige. Immagine dell'autore.

Anche se la figura che abbiamo restituito racconta una storia sui trend dei nostri dati, è difficile identificare pozzi specifici e i valori tra i punti di misurazione.

Utilizzare Plotly per rendere il nostro grafico interattivo

Un modo per cambiare istantaneamente questo problema sarebbe quello di utilizzare la libreria Plotly. Plotly è una grande libreria per creare grafici altamente interattivi che sono facili da mettere insieme.

Plotly ha due modi principali per costruire grafici: Plotly Express e Plotly Graph Objects.

Plotly Express fornisce un’interfaccia ad alto livello per Plotly e utilizza una sintassi semplice per creare potenti grafici interattivi. Tuttavia, la personalizzazione di determinati aspetti del grafico può richiedere molto lavoro e può essere difficile da fare. Qui entra in gioco la parte Graph Objects della libreria. Fornisce un’interfaccia a basso livello che fornisce un controllo completo sulle nostre figure; tuttavia, significa che mettere insieme una figura è leggermente più complesso.

In questo esempio, utilizzeremo Graph Objects, che può essere importato come segue:

import plotly.graph_objects as go

Successivamente, possiamo definire i nostri array x e y utilizzando la funzione linspace di Numpy.

In questo modo verranno creati due array della stessa dimensione della griglia di dati creata in precedenza.

Crea anche due liste per longitudine e latitudine. Questi valori si estendono oltre i valori di longitudine e latitudine dei dati e ci consentono di avere uno spazio intorno ai bordi dei nostri punti dati.

longitude = [1.5, 4.5]latitude = [57.5, 62]x = np.linspace(longitude[0], longitude[1], zstar.shape[1])y = np.linspace(latitude[0], latitude[1], zstar.shape[0])

Usando Matplotlib, potremmo visualizzare questo tipo di dati utilizzando la funzione imshow.

Anche se Plotly ha anche un grafico imshow, non possiamo (finora, al momento della stesura) controllare l’estensione del grafico. Questo significa che non possiamo specificare i valori per i punti di inizio degli assi.

Per visualizzare la nostra griglia di dati, possiamo passare all’utilizzo della mappa termica di Plotly.

La mappa termica colora ogni cella di dati all’interno della nostra griglia in base al suo valore. Puoi saperne di più sulle mappe termiche nel mio articolo su Seaborn.

Possiamo utilizzare il seguente codice per creare la nostra mappa termica con Plotly Graph Objects.

fig = go.Figure()fig.add_trace(go.Heatmap(z=zstar, x=x, y=y))fig.update_xaxes(range=(longitude[0], longitude[1]))fig.update_yaxes(range=(latitude[0], latitude[1]))fig.update_layout(autosize=False, width=800, height=800)fig.show()

Prima di tutto, creiamo un oggetto figura e aggiungiamo una traccia. Questa traccia contiene i nostri dati di posizione x e y, così come la nostra griglia ( zstar ) creata da Kriging.

Imposteremo anche la dimensione della figura su 800 x 800, il che ci darà un grafico abbastanza grande da lavorare all’interno dei notebook Jupyter.

Dopo aver eseguito il codice precedente, otteniamo la mappa termica con tutti i nostri valori di dati e gli assi visualizzati all’interno della corretta gamma.

Mappa termica di Plotly Graph Objects che mostra le variazioni nella nostra misurazione di compressione acustica lungo lo scaffale continentale norvegese. Immagine dell'autore.

La cosa fantastica di questo grafico è che possiamo passarci sopra con il mouse e visualizzare i valori in qualsiasi punto. Inoltre, Plotly ci consente di ingrandire sezioni per una visualizzazione più dettagliata.

Anche se il grafico precedente è fantastico, mancano ulteriori informazioni che aiuterebbero il lettore, come le nostre posizioni dei pozzi e anche le etichette per i nostri assi.

Per aggiungere le posizioni dei nostri pozzi, dobbiamo aggiungere una seconda traccia. Questa volta utilizzando go.scatter() e passando i valori di latitudine e longitudine dal nostro dataframe. Possiamo anche controllare l’aspetto di questi punti aggiungendo un dizionario per i nostri marcatori. In questo esempio, li impostiamo su nero.

fig = go.Figure()fig.add_trace(go.Heatmap(z=zstar, x=x, y=y))# Aggiungi le posizioni dei pozzi fig.add_trace(go.Scatter(x=df['LON'], y=df['LAT'],                         mode='markers', marker=dict(color='black')))fig.update_xaxes(range=(longitude[0], longitude[1]))fig.update_yaxes(range=(latitude[0], latitude[1]))fig.update_layout(autosize=False, width=800, height=800)fig.show()
Mappa di calore degli oggetti grafici Plotly che mostra le posizioni di misura (pozzi) e le variazioni all'interno della nostra misura di compressione acustica di rallentamento su tutta la piattaforma continentale norvegese. Immagine dell'autore.

Ora possiamo vedere dove si trovano i nostri pozzi; tuttavia, se ci soffermiamo sui marcatori, tutto ciò che otteniamo sono i valori di latitudine e longitudine. Questo è utile fino a un certo punto; tuttavia, sarebbe bello sapere a quale pozzo il marcatore si riferisce e quale valore di DTC è stato misurato per quel pozzo.

Per risolvere questo problema, possiamo creare il nostro testo di hover direttamente nel dataframe come una nuova colonna. Questo è utile se vogliamo usarlo in seguito per altre visualizzazioni.

fig = go.Figure()fig.add_trace(go.Heatmap(z=zstar, x=x, y=y,                          colorbar=dict(title='DTC (us/ft)',                                       title_font=dict(size=18))))df['hover_text'] = df.apply(lambda row: f"""<b>{row['WELL']}</b>                            <br>Latitudine: {row['LAT']}                            <br>Longitudine: {row['LON']}                            <br>Valore del log: {round(row['DTC_MEAN'], 2)}""",                             axis=1)fig.add_trace(go.Scatter(x=df['LON'], y=df['LAT'],                         mode='markers', marker=dict(color='black'),                        name='Pozzi', text=df['hover_text'], hoverinfo='text', showlegend=True))fig.update_xaxes(range=(longitude[0], longitude[1]),                  title='Longitudine')fig.update_yaxes(range=(latitude[0], latitude[1]),                  title='Latitudine')fig.update_layout(autosize=False, width=800, height=800,                   legend=dict(x=1, y=0, xanchor='auto', yanchor='auto',                               bgcolor='rgba(255, 255, 255, 0.5)'))fig.show()

Quando eseguiamo il codice sopra, otteniamo il seguente grafico.

Mappa di calore degli oggetti grafici Plotly con interattività aggiunta. Questa visualizzazione mostra le posizioni di misura (pozzi) e le variazioni all'interno della nostra misura di compressione acustica di rallentamento. Immagine dell'autore.

Ora, quando passiamo il mouse su uno qualsiasi dei pozzi, otteniamo il nome del pozzo, seguito dalla latitudine e longitudine e dal valore del registro. In questo caso, stiamo visualizzando la compressione acustica di rallentamento.

Sommario

In questo breve tutorial, abbiamo visto come possiamo andare oltre una semplice e statica figura di matplotlib delle nostre variazioni di misura. La funzionalità extra e l’interattività di Plotly lo rendono una scelta eccellente per visualizzare le variazioni geospaziali nelle misurazioni dei registri di pozzo.

L’interattività extra ci consente di identificare a quale pozzo si riferisce ciascun punto, quale era il valore misurato in quella posizione e di interpretare i valori della griglia che non hanno una misurazione diretta.

Dataset utilizzato

Il dataset utilizzato in questo articolo è un sottoinsieme di un dataset di training utilizzato come parte di una competizione di Machine Learning organizzata da Xeek e FORCE 2020 (Bormann et al., 2020). È rilasciato sotto licenza NOLD 2.0 dal governo norvegese, i dettagli della quale possono essere trovati qui: Norwegian Licence for Open Government Data (NLOD) 2.0. L’intero dataset è accessibile qui.

Il riferimento completo per il dataset è:

Bormann, Peter, Aursand, Peder, Dilib, Fahad, Manral, Surrender e Dischington, Peter. (2020). FORCE 2020 Well well log and lithofacies dataset per la competizione di machine learning [Data set]. Zenodo. http://doi.org/10.5281/zenodo.4351156

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

In secondo luogo, puoi vivere l’esperienza Nisoo completa e supportare 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 denaro con la tua scrittura.

Se ti iscrivi usando 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.