Drillhole creation and quick visualiation#

import geolime as geo
from pyproj import CRS
import pyvista as pv

pv.set_jupyter_backend('panel')


geo.Project().set_crs(CRS("EPSG:20350"))
/tmp/ipykernel_2837/3471980330.py:5: PyVistaDeprecationWarning: `panel` backend is deprecated and is planned for future removal.
  pv.set_jupyter_backend('panel')

Loading DrillHoles#

dh = geo.read_file("../data/dh_hyper.geo")
dh.user_properties()
['X_COLLAR',
 'Y_COLLAR',
 'Z_COLLAR',
 'X_M',
 'Y_M',
 'Z_M',
 'X_B',
 'Y_B',
 'Z_B',
 'X_E',
 'Y_E',
 'Z_E',
 'Fe_pct',
 'Al2O3',
 'SiO2_pct',
 'K2O_pct',
 'CaO_pct',
 'MgO_pct',
 'TiO2_pct',
 'P_pct',
 'S_pct',
 'Mn_pct',
 'Fe_ox_ai',
 'hem_over_goe',
 'kaolin_abundance',
 'kaolin_composition',
 'wmAlsmai',
 'wmAlsmci',
 'carbai3pfit',
 'carbci3pfit',
 'Sample_ID',
 'Fe',
 'Fe2o3',
 'P',
 'S',
 'SiO2',
 'MnO',
 'Mn',
 'CaO',
 'K2O',
 'MgO',
 'Na2O',
 'TiO2',
 'LOI_100',
 'Depth']

The basic properties of a drillholes object already have unit specify

dh.property("X_M").unit
meter

Unit can also be specified in the Project for each property.

Property units are managed using the Pint python pacakge (https://pint.readthedocs.io/en/stable/index.html). Default unit are already available (https://github.com/hgrecco/pint/blob/master/pint/default_en.txt) and other can be added to a GeoLime project

This will allow to specify the percent property to each property of a GeoLime object.

geo.Project().unit_registry.define("percent = 1e-2 frac = pct")

Using the percent unit defined, we can now specify it to all other related property, especially the ones with _pct in their names.

for prop in dh.properties():
    if "_pct" in dh.property(prop).name:
        dh.property(prop).unit = geo.Project().unit_registry.pct
dh.property("Fe_pct").unit
percent

Graphic representations#

geo.scatter(geo_object=dh, property_x="X_M", property_y="Z_M")
geo.scatter(geo_object=dh, property_x="Y_M", property_y="Z_M")

Points with no value can be hidden using extra keywords from the folium library: https://python-visualization.github.io/folium/quickstart.html#Getting-Started

dh.plot_2d(property="Fe_pct", agg_method="mean", interactive_map=True, style_kwds={"fillColor": "none"})
Make this Notebook Trusted to load map: File -> Trust Notebook
geo.scatter(geo_object=dh, property_x="Fe_pct", property_y="Z_M", marginal_plot="Histogram")

Exploratory Analysis#

df_pv = dh.to_pyvista('Fe_pct')
pl = pv.Plotter()
pl.add_mesh(df_pv.tube(radius=10))
pl.set_scale(zscale=20)

pl.show()

Geological section#

geo.scatter(
    geo_object=dh, 
    property_x="Fe_pct", 
    property_y="Z_M", 
    region="(Y_M > 7475791.8 - 400) &  (Y_M < 7475791.8 + 400)"
)

Scatter function takes also into account all layout properties from plotly : https://plotly.com/python/reference/layout/.

As GeoLime plotting functions returns Plotly Figure, they can be stored in a variable.

f = geo.scatter(
    geo_object=dh, 
    property_x="X_M", 
    property_y="FROM", 
    region="(Y_M > 7475791.8 - 20) &  (Y_M < 7475791.8 + 20)", 
    yaxis_autorange="reversed"
)

Plotly figures can then be exported to

  • standard image format (PNG, PDF, JPEG) for static export

  • HTML format for interactive export and sharing only figure without code

  • JSON format to be used in other software or in a Web Application

  • python dictionnary to understand figure architecture and modify every elements

f.to_dict()
{'data': [{'hoverlabel': {'namelength': -1},
   'marker': {'line': {'color': 'black', 'width': 1}},
   'mode': 'markers',
   'x': array([547147.6, 547147.6, 547147.6, ..., 547595. , 547595. , 547595. ]),
   'xaxis': 'x',
   'y': array([ 0.,  1.,  2., ..., 46., 47., 48.]),
   'yaxis': 'y',
   'type': 'scattergl'}],
 'layout': {'template': {'data': {'histogram2dcontour': [{'type': 'histogram2dcontour',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'choropleth': [{'type': 'choropleth',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'histogram2d': [{'type': 'histogram2d',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'heatmap': [{'type': 'heatmap',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'heatmapgl': [{'type': 'heatmapgl',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'contourcarpet': [{'type': 'contourcarpet',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'contour': [{'type': 'contour',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'surface': [{'type': 'surface',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'mesh3d': [{'type': 'mesh3d',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'scatter': [{'fillpattern': {'fillmode': 'overlay',
       'size': 10,
       'solidity': 0.2},
      'type': 'scatter'}],
    'parcoords': [{'type': 'parcoords',
      'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterpolargl': [{'type': 'scatterpolargl',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'bar': [{'error_x': {'color': '#2a3f5f'},
      'error_y': {'color': '#2a3f5f'},
      'marker': {'line': {'color': '#E5ECF6', 'width': 0.5},
       'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}},
      'type': 'bar'}],
    'scattergeo': [{'type': 'scattergeo',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterpolar': [{'type': 'scatterpolar',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'histogram': [{'marker': {'pattern': {'fillmode': 'overlay',
        'size': 10,
        'solidity': 0.2}},
      'type': 'histogram'}],
    'scattergl': [{'type': 'scattergl',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatter3d': [{'type': 'scatter3d',
      'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}},
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scattermapbox': [{'type': 'scattermapbox',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterternary': [{'type': 'scatterternary',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scattercarpet': [{'type': 'scattercarpet',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'carpet': [{'aaxis': {'endlinecolor': '#2a3f5f',
       'gridcolor': 'white',
       'linecolor': 'white',
       'minorgridcolor': 'white',
       'startlinecolor': '#2a3f5f'},
      'baxis': {'endlinecolor': '#2a3f5f',
       'gridcolor': 'white',
       'linecolor': 'white',
       'minorgridcolor': 'white',
       'startlinecolor': '#2a3f5f'},
      'type': 'carpet'}],
    'table': [{'cells': {'fill': {'color': '#EBF0F8'},
       'line': {'color': 'white'}},
      'header': {'fill': {'color': '#C8D4E3'}, 'line': {'color': 'white'}},
      'type': 'table'}],
    'barpolar': [{'marker': {'line': {'color': '#E5ECF6', 'width': 0.5},
       'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}},
      'type': 'barpolar'}],
    'pie': [{'automargin': True, 'type': 'pie'}]},
   'layout': {'autotypenumbers': 'strict',
    'colorway': ['#636efa',
     '#EF553B',
     '#00cc96',
     '#ab63fa',
     '#FFA15A',
     '#19d3f3',
     '#FF6692',
     '#B6E880',
     '#FF97FF',
     '#FECB52'],
    'font': {'color': '#2a3f5f'},
    'hovermode': 'closest',
    'hoverlabel': {'align': 'left'},
    'paper_bgcolor': 'white',
    'plot_bgcolor': '#E5ECF6',
    'polar': {'bgcolor': '#E5ECF6',
     'angularaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'radialaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}},
    'ternary': {'bgcolor': '#E5ECF6',
     'aaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'baxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'caxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}},
    'coloraxis': {'colorbar': {'outlinewidth': 0, 'ticks': ''}},
    'colorscale': {'sequential': [[0.0, '#0d0887'],
      [0.1111111111111111, '#46039f'],
      [0.2222222222222222, '#7201a8'],
      [0.3333333333333333, '#9c179e'],
      [0.4444444444444444, '#bd3786'],
      [0.5555555555555556, '#d8576b'],
      [0.6666666666666666, '#ed7953'],
      [0.7777777777777778, '#fb9f3a'],
      [0.8888888888888888, '#fdca26'],
      [1.0, '#f0f921']],
     'sequentialminus': [[0.0, '#0d0887'],
      [0.1111111111111111, '#46039f'],
      [0.2222222222222222, '#7201a8'],
      [0.3333333333333333, '#9c179e'],
      [0.4444444444444444, '#bd3786'],
      [0.5555555555555556, '#d8576b'],
      [0.6666666666666666, '#ed7953'],
      [0.7777777777777778, '#fb9f3a'],
      [0.8888888888888888, '#fdca26'],
      [1.0, '#f0f921']],
     'diverging': [[0, '#8e0152'],
      [0.1, '#c51b7d'],
      [0.2, '#de77ae'],
      [0.3, '#f1b6da'],
      [0.4, '#fde0ef'],
      [0.5, '#f7f7f7'],
      [0.6, '#e6f5d0'],
      [0.7, '#b8e186'],
      [0.8, '#7fbc41'],
      [0.9, '#4d9221'],
      [1, '#276419']]},
    'xaxis': {'gridcolor': 'white',
     'linecolor': 'white',
     'ticks': '',
     'title': {'standoff': 15},
     'zerolinecolor': 'white',
     'automargin': True,
     'zerolinewidth': 2},
    'yaxis': {'gridcolor': 'white',
     'linecolor': 'white',
     'ticks': '',
     'title': {'standoff': 15},
     'zerolinecolor': 'white',
     'automargin': True,
     'zerolinewidth': 2},
    'scene': {'xaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2},
     'yaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2},
     'zaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2}},
    'shapedefaults': {'line': {'color': '#2a3f5f'}},
    'annotationdefaults': {'arrowcolor': '#2a3f5f',
     'arrowhead': 0,
     'arrowwidth': 1},
    'geo': {'bgcolor': 'white',
     'landcolor': '#E5ECF6',
     'subunitcolor': 'white',
     'showland': True,
     'showlakes': True,
     'lakecolor': 'white'},
    'title': {'x': 0.05},
    'mapbox': {'style': 'light'}}},
  'xaxis': {'title': {'text': 'X_M'},
   'showline': True,
   'linewidth': 2,
   'linecolor': 'black',
   'mirror': True,
   'rangemode': 'nonnegative'},
  'yaxis': {'title': {'text': 'FROM'},
   'showline': True,
   'linewidth': 2,
   'linecolor': 'black',
   'mirror': True,
   'rangemode': 'nonnegative',
   'autorange': 'reversed'},
  'showlegend': False}}

For example, we can change the color by setting a property from the drillholes, here we color the point using the Iron content

f["data"][0]["marker"]["color"] = dh.data("Fe_pct", "(Y_M > 7475791.8 - 20) &  (Y_M < 7475791.8 + 20)")
f["data"][0]["marker"]["line"]["width"] = 0
f
f["data"][0]["marker"]["colorscale"] = "cividis"
f

Correlations between elements#

geo.correlation_heatmap(
    geo_object=dh, 
    properties=[
        "Mn_pct", "P_pct", "Fe_pct", "CaO_pct", "MgO_pct", "S_pct", "Al2O3", "TiO2_pct", "SiO2_pct", "K2O_pct"
    ]
)
geo.scatter(geo_object=dh, property_x="Al2O3", property_y="Fe_pct", marginal_plot=geo.ScatterMethod.HISTOGRAM)

Histograms#

Iron#

geo.histogram_plot(
    data=[
        {"object": dh, "property": "Fe_pct", "region": "FROM <= 10"},
        {"object": dh, "property": "Fe_pct", "region": "FROM > 10"}
    ],
    nbins=30
)

Aluminium#

geo.histogram_plot(data=[{"object": dh, "property": "Al2O3"}], nbins=30)

Titanium#

geo.histogram_plot(data=[{"object": dh, "property": "TiO2_pct"}], nbins=30)

Conclusions#

As we can see with the visualization above, the main element in this area is Iron, mainly as an oxyde (Hematite/Goethite). Secondly, the geological sections and various scatter showed us that the iron is located in two separate deposits, the first one being located near 10 meters deep, and the other around 50m. This distribution of iron seems to show again in the histograms by its bimodal adspect.

Our tools have also revealed the presence of Al2O3 and TiO2, which are highly correlated (0.7 according to our heatmap, and located in the same areas, indicating a common backgroud and deposit history. However, their distribution is way lower than the iron one (Maximum 60% for the iron against 30% for the Aluminium and 3% Titanium), and they exist as punctual traces, not well defined deposits.