Utilizando Gráficos de Superficie 3D de Plotly para Visualizar Superficies Geológicas.

Using Plotly's 3D Surface Graphs to Visualize Geological Surfaces.

Visualizando el subsuelo usando bibliotecas de visualización de datos de Python

Trama de superficie 3D de la Formación Hugin. Imagen del autor.

Dentro de la geociencia, es esencial tener una comprensión completa de las superficies geológicas presentes en el subsuelo. Al conocer la ubicación exacta de la formación y su geometría, se vuelve más fácil identificar posibles nuevos objetivos para la exploración de petróleo y gas, así como posibles ubicaciones de captura y almacenamiento de carbono. Hay una variedad de métodos que podemos utilizar para refinar estas superficies que van desde datos sísmicos hasta formaciones derivadas de registros de pozos. Con mayor frecuencia, estas técnicas se usan en combinación entre sí para refinar la superficie final.

Este artículo continúa a partir de mis artículos anteriores, que se centraron en el proceso de extrapolar las mediciones de registros de pozos en una región para comprender y visualizar las variaciones geoespaciales. En este artículo, veremos cómo podemos crear superficies 3D utilizando gráficos interactivos de Plotly.

Dado que modelar superficies geológicas es un proceso complejo y a menudo implica múltiples iteraciones y refinamientos, este artículo demuestra un ejemplo muy simple de cómo podemos visualizar estos datos con Python.

Para ver cómo podemos usar Plotly para visualizar nuestra formación geológica superior en un área, usaremos dos conjuntos de datos.

El primer conjunto de datos se deriva de 28 intersecciones con la formación derivada de selecciones de pozos, que se utilizan como entrada para kriging para producir una superficie de baja resolución. En contraste, el segundo conjunto de datos se deriva de datos sísmicos interpretados, proporcionando una superficie de mucha mayor resolución.

Ambos conjuntos de datos son del conjunto de datos Equinor Volve. Los detalles de los cuales se encuentran al final de este artículo.

También puede consultar los siguientes artículos dentro de esta mini-serie en los siguientes enlaces:

  • Plotly y Python: creación de mapas de calor interactivos para datos petrofísicos y geológicos
  • Utilización de pykrige y matplotlib para visualización espacial de variaciones geológicas
  • Visualización de trayectorias de pozos en gráficos de línea 3D con Plotly Express

Importación de bibliotecas y datos

Antes de intentar trabajar con los datos, primero debemos importar las bibliotecas que necesitaremos. Éstos son:

  • pandas — para leer nuestros datos, que están en formato csv
  • matplotlib para crear nuestra visualización
  • pykrige para llevar a cabo el kriging
  • numpy para algunos cálculos numéricos
  • plotly.graph_objects para visualizar superficies en 3D
import pandas as pdimport matplotlib.pyplot as pltimport plotly.graph_objects as gofrom pykrige import OrdinaryKrigingimport numpy as np

A continuación, podemos cargar los datos usando pd.read_csv().

Dado que estos datos contienen información sobre superficies geológicas de todos los pozos dentro del campo Volve, podemos usar query() para extraer los datos de la formación que necesitamos. En este caso, estaremos viendo la Formación Hugin.

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

Cuando ejecutamos el código anterior, obtenemos la siguiente tabla. Es posible que note que algunos pozos han encontrado la Formación Hugin varias veces. Esto probablemente se deba a que los pozos penetraron la formación varias veces, ya sea debido a la geometría del pozo o de la formación.

Marco de datos de pandas que contiene información sobre las selecciones de formación para la Formación Hugin en el campo Volve. Imagen del autor.

Extrapolando TVDSS para generar una superficie geológica

En mis artículos anteriores, me he centrado en cómo podemos utilizar un proceso conocido como kriging para “rellenar los huecos” entre los puntos de medición. No cubriremos los detalles de este proceso en este artículo; sin embargo, puede consultar este artículo para obtener más información.

Una vez que se ha cargado nuestros datos, podemos ejecutar el proceso de kriging llamando al método OrdinaryKriging de pykrige.

Dentro de esta llamada, pasamos nuestros datos de x e y que representan la posición de este y norte donde el pozo encontró la formación dentro del subsuelo.

Como queremos generar una superficie de la formación Hugin, necesitamos usar la medida de TVDSS — Profundidad Vertical Verdadera Submarina —. Esto da una verdadera reflexión de lo profundo que está la superficie por debajo del datum seleccionado.

OK = OrdinaryKriging(x=df_hugin['Easting'],                       y=df_hugin['Northing'],                       z=df_hugin['TVDSS'],                      variogram_model='linear',                      verbose=True, enable_plotting=True)
Resultados de kriging ordinario para la formación Hugin. Imagen del autor.

Una vez generado el modelo, podemos aplicarlo a dos matrices que cubren todo el rango de los puntos de penetración del pozo.

Esto nos permite generar una cuadrícula de valores que luego se pasan al objeto OrdinaryKriging que generamos anteriormente.

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

Para terminar, podemos generar una simple vista de mapa 2D de nuestra superficie usando el método imshow de matplotlib.

fig, ax = plt.subplots(figsize=(15,5))# Crea una imagen en 2D de los datos en 'zstar'# El parámetro 'extent' establece los límites de la imagen en coordenadas de datos# El parámetro 'origin' establece la parte de la imagen que corresponde al origen de los ejesimagen = ax.imshow(zstar, extent=(433986, 438607, 6477539, 6479393),                   origin='lower')# Establecer las etiquetas para el eje x e yax.set_xlabel('Ubicación de X (m)', fontsize=14, fontweight='bold')ax.set_ylabel('Ubicación de Y (m)', fontsize=14, fontweight='bold')# Agregar contornoscontours = ax.contour(gridx, gridy, zstar, colors='black')colorbar = fig.colorbar(image)colorbar.set_label('DTC (us/ft)', fontsize=14, fontweight='bold')# Mostrar la tramaplt.show()
Mapa de superficie y contorno 2D de la formación de Hugin después de aplicar kriging. Imagen del autor.

Creando un simple gráfico de superficie 3D con Plotly

Para convertir nuestra superficie 2D en 3D, necesitamos usar Plotly. Podríamos usar matplotlib para hacer esto; sin embargo, por mi experiencia, es más fácil, más suave y más interactivo generar las visualizaciones 3D con Plotly.

En el siguiente código, primero creamos nuestra cuadrícula de coordenadas. Para hacer esto, usamos la función linspace de numpy. Esta función creará un conjunto de números uniformemente espaciados en un rango especificado. Para nuestro conjunto de datos y ejemplo, el rango se extiende desde el mínimo hasta el máximo de xgrid_extent e ygrid_extent.

El número total de valores utilizados dentro de este rango será equivalente al número de elementos x e y presentes en la cuadrícula zstar que creamos arriba.

Una vez que se forma nuestra cuadrícula, llamamos a Plotly.

Primero, creamos nuestro objeto de figura y luego usamos fig.add_trace para agregar nuestra trama de superficie 3D a la figura.

Una vez que se ha agregado esto, necesitamos ajustar el diseño de nuestra trama para que tengamos etiquetas de eje, un ancho y altura definidos y algo de relleno.

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='Ubicación X',                    yaxis_title='Ubicación Y',                    zaxis_title='Profundidad'),                  width=1000,                  height=800,                  margin=dict(r=20, l=10, b=10, t=10))fig.show()

Cuando ejecutamos el código anterior, obtenemos la siguiente gráfica interactiva que muestra la superficie geológica de la formación Hugin basada en los múltiples encuentros de los pozos perforados.

Trama de superficie 3D de la Formación Hugin generada utilizando Plotly. Imagen del autor.

Visualización de una superficie completamente interpretada con Plotly

El conjunto de datos Volve tiene varias superficies totalmente interpretadas que se han generado a partir de interpretaciones geológicas, incluidos datos sísmicos.

Estos datos contienen las ubicaciones x e y de los puntos de datos en todo el campo, así como nuestros datos TVDSS (z).

Los datos suministrados en el portal de datos de Volve están en forma de archivo .dat, sin embargo, con un poco de manipulación dentro de un editor de texto, se puede convertir fácilmente a un archivo CSV y cargarse usando pandas.

hugin_formation_surface = pd.read_csv('Data/Volve/Hugin_Fm_Top+ST10010ZC11_Near_190314_adj2_2760_EasyDC+STAT+DEPTH.csv')
Ubicaciones X, Y y Z de la Formación Hugin. Imagen del autor.

Una vez que tenemos los datos cargados, podemos hacer las cosas más fáciles para nosotros extrayendo los datos x, y y z a variables.

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

Luego necesitamos crear una cuadrícula espaciada regularmente entre nuestras posiciones mínimas y máximas dentro de las ubicaciones de datos x e y. Esto se puede hacer usando meshgrid de numpy.

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

Hay varias formas de interpolar entre una serie de puntos de datos. El método elegido dependerá de la forma en que se encuentren sus datos (puntos de datos muestreados regularmente frente a muestreados irregularmente), el tamaño de los datos y la potencia informática.

Si tenemos un conjunto de datos grande como este, algunos de los métodos como la Función de Base Radial serán mucho más costosos computacionalmente.

Para este ejemplo, usaremos el método LinearNDInterpolator dentro de scipy para construir nuestro modelo y luego aplicarlo a nuestra variable z (TVDSS).

Para interpolar entre puntos, necesitamos reformar xi, yi a matrices 1D para la interpolación, ya que LinearNDInterpolator espera una matriz 1D.

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

Una vez que se ha calculado esto, podemos pasar a crear nuestra 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='Este (m)',                    yaxis_title='Norte (m)',                    zaxis_title='Profundidad',                    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()

Cuando ejecutamos el código anterior, obtenemos el siguiente gráfico de superficie 3D de la Formación Hugin.

Superficie geológica completamente interpretada de la Formación Hugin. Imagen del autor.

Cuando comparamos esta gráfica con la generada a partir de las mediciones de los pozos, definitivamente podemos ver similitudes en la forma general con el valle en el medio. Sin embargo, la superficie derivada de la sísmica proporciona mucho más detalle que la de los topos de formación derivados del pozo.

Comparación de la superficie de la Formación Hugin generada a partir de mediciones de registros de pozos dispersos (izquierda) con una superficie generada a partir de datos sísmicos (derecha). Imagen del autor.

Resumen

En este breve tutorial, hemos visto cómo podemos utilizar la gráfica de superficie 3D de Plotly para generar una visualización interactiva 3D de una superficie geológica. Con los topos de la formación derivados del registro de pozos, podemos generar una superficie 3D con un aspecto muy básico. Esto se debe a que las mediciones están restringidas a donde los pozos han intersectado la Formación Hugin, lo que significa que obtenemos una superficie de baja resolución.

En contraste, podemos generar una impresión mucho más realista de la formación si tenemos puntos de medición más detallados, como los horizontes derivados de la sísmica.

Ambos métodos son igualmente válidos, sin embargo, debemos tener en cuenta que al extrapolar a partir de los topos de formación que se han derivado solo de las mediciones de los registros de pozos, es posible que no hayamos podido generar una imagen completa de esa formación en toda el área.

Conjunto de datos utilizado

Los datos utilizados en este tutorial son una subsección del conjunto de datos Volve que Equinor lanzó en 2018. Todos los detalles del conjunto de datos, incluida la licencia, se pueden encontrar en el siguiente enlace

Conjunto de datos del campo Volve

Equinor ha lanzado un conjunto completo de datos del campo Volve, 2008-2016. Haz clic aquí para descargar para estudiar, investigar…

www.equinor.com

La licencia de datos de Volve se basa en la licencia CC BY 4.0. Todos los detalles del acuerdo de licencia se pueden encontrar aquí:

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

Gracias por leer. Antes de irte, definitivamente deberías suscribirte a mi contenido y recibir mis artículos en tu correo electrónico. ¡Puedes hacerlo aquí!

En segundo lugar, puedes obtener la experiencia completa de Zepes y apoyar a miles de otros escritores y a mí mismo al suscribirte a una membresía. Solo te cuesta $5 al mes, y tendrás acceso completo a todos los fantásticos artículos de Zepes, así como la oportunidad de ganar dinero con tu escritura.

Si te registras utilizando mi enlace , me apoyarás directamente con una parte de tu cuota y no te costará más. Si lo haces, muchas gracias por tu apoyo.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Aprendizaje automático a gran escala Paralelismo de modelos frente a paralelismo de datos

A medida que los modelos se vuelven cada vez más complejos y los conjuntos de datos se vuelven gigantescos, la necesi...

Inteligencia Artificial

Top Herramientas/Startups de Datos Sintéticos para Modelos de Aprendizaje Automático en 2023

La información creada intencionalmente en lugar de ser el resultado de eventos reales se conoce como datos sintéticos...

Ciencia de Datos

De Python a Julia Manipulación de Datos Básica y Análisis Exploratorio de Datos (EDA)

Como lenguaje de programación emergente en el espacio del cómputo estadístico, Julia está ganando cada vez más atenci...

Inteligencia Artificial

Conoce a Prismer Un modelo de visión-lenguaje de código abierto con un conjunto de expertos.

Varios modelos recientes de visión y lenguaje han demostrado notables habilidades de generación multimodal. Pero típi...

Inteligencia Artificial

Creando un GPT Climático Utilizando la API de Energía de la NASA

En este artículo exploramos la nueva función de los GPT de OpenAI, que ofrece una forma sin código de crear rápidamen...