Drillhole creation and quick visualiation#
Here along GeoLime are used CRS from pyproj in order to deal with Coordinates Reference System and display data on a map with a background, pyvista in order to visualise data in 3D and pandas to read the assay file obtained in the cleaning notebook.
import geolime as geo
from pyproj import CRS
import pyvista as pv
import pandas as pd
pv.set_jupyter_backend('html')
geo.Project().set_crs(CRS("EPSG:20350"))
GeoLime Drillholes Creation#
The next command will use the Geo Lime library to draw an interactive map of the iron concentration. First we need to import the survey and collar file to have all the informations about the drillholes.
Note
Survey File Survey File was created as it is not provided by the CSIRO. In this case of vertical drillholes, a survey file is optionnal as GeoLime will consider it automatically. For the purpose of this a survey file is however created in order to behave like most cases.
survey = geo.datasets.load("rocklea_dome/survey.csv")
collar = geo.datasets.load("rocklea_dome/collar.csv")
assay = pd.read_csv("../data/assay_hyper.csv")
Project Definition#
The CRS can be set using the Project() object, allowing to define parameters once and not for every new imported data.
geo.Project().set_crs(CRS("EPSG:20350"))
Drillholes Creation#
Then we can create the drillholes and draw the map showing the average iron weight percentage of each hole.
dh = geo.create_drillholes(
name="rck_assay",
collar=collar,
assays=assay,
survey=survey
)
2024-12-03 15:36:01,119 [INFO] GeoLime Project - |GEOLIME|.drillholes_api.py : Following mapping has been identified: {
"HOLEID": "Hole_ID",
"X_COLLAR": "X",
"Y_COLLAR": "Y",
"Z_COLLAR": "RL_AHD",
"AZIMUTH": "Azi_mag",
"DEPTH_SURVEY": "Distance",
"DIP": "Dip",
"FROM": "From",
"TO": "To"
}
Like Pandas library, GeoLime uses the describe method to quickly access to the aggregated statistics of an object.
dh.describe()
| __TOPO_LEVEL__ | __TOPO_TYPE__ | __TOPO_ELEMENT_V1__ | __TOPO_ELEMENT_V2__ | FROM | TO | X_COLLAR | Y_COLLAR | Z_COLLAR | X_M | ... | SiO2 | MnO | Mn | CaO | K2O | MgO | Na2O | TiO2 | LOI_100 | Depth | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 7108.0 | 7108.0 | 7108.000000 | 7108.000000 | 7108.000000 | 7108.000000 | 7108.000000 | 7.108000e+03 | 7108.000000 | 7108.000000 | ... | 7036.000000 | 7036.0 | 7036.000000 | 7036.000000 | 7036.000000 | 7036.000000 | 7036.000000 | 7036.000000 | 7036.000000 | 7108.000000 |
| mean | 2.0 | 1.0 | 3649.240293 | 3650.240293 | 20.568655 | 21.568655 | 547413.687521 | 7.475481e+06 | 458.500774 | 547413.687521 | ... | 20.022739 | 0.0 | 0.058710 | 1.061883 | 0.130430 | 0.885746 | 0.001279 | 0.448157 | 0.000007 | 42.645751 |
| std | 0.0 | 0.0 | 2111.443717 | 2111.443717 | 13.834178 | 13.834178 | 685.729896 | 1.587386e+03 | 7.467718 | 685.729896 | ... | 21.012233 | 0.0 | 0.133017 | 3.609818 | 0.491768 | 1.982652 | 0.107295 | 0.537459 | 0.000608 | 11.275263 |
| min | 2.0 | 1.0 | 0.000000 | 1.000000 | 0.000000 | 1.000000 | 545494.900000 | 7.472793e+06 | 441.000000 | 545494.900000 | ... | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 7.000000 |
| 25% | 2.0 | 1.0 | 1816.750000 | 1817.750000 | 9.000000 | 10.000000 | 546904.700000 | 7.474003e+06 | 453.800000 | 546904.700000 | ... | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 36.000000 |
| 50% | 2.0 | 1.0 | 3650.500000 | 3651.500000 | 19.000000 | 20.000000 | 547586.100000 | 7.475604e+06 | 458.200000 | 547586.100000 | ... | 12.735000 | 0.0 | 0.010000 | 0.110000 | 0.025000 | 0.310000 | 0.000000 | 0.267000 | 0.000000 | 46.000000 |
| 75% | 2.0 | 1.0 | 5479.250000 | 5480.250000 | 31.000000 | 32.000000 | 547947.600000 | 7.476004e+06 | 463.600000 | 547947.600000 | ... | 33.555000 | 0.0 | 0.090000 | 0.300000 | 0.082000 | 0.720000 | 0.000000 | 0.692000 | 0.000000 | 51.000000 |
| max | 2.0 | 1.0 | 7298.000000 | 7299.000000 | 60.000000 | 61.000000 | 548498.100000 | 7.479595e+06 | 478.600000 | 548498.100000 | ... | 92.810000 | 0.0 | 6.160000 | 40.820000 | 21.250000 | 20.010000 | 9.000000 | 10.000000 | 0.051000 | 61.000000 |
8 rows × 51 columns
The basic properties of a drillholes object already have unit specify.
dh.property("X_M").unit
Unit can also be specified in the Project for each property.
Property units are managed using the Pint python package (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
Graphic representations#
Most of GeoLime objects are 3D objects (Drillholes, BlockModel) and their visualisation on a map in 2D needs to “aggregate” values on the vertical dimensions. Drillholes are aggregated alond the hole and BlockModel are aggregated along a “column” of Block, being the block with the same X and Y.
dh.plot_2d(property="Fe", agg_method="mean", interactive_map=True)
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"})
Aggregation along axes can be plotted using the scatter function. Unlike a cross section where only a slice is viewed, here all data are visualised.
In drillholes objects there are 3 coordinates availables for each composite :
the coordinates of the begininng of the composites (X_B, Y_B and Z_B)
the coordinates of the midpoint of the composites (X_M, Y_M and Z_M)
the coordinates of the end of the composites (X_E, Y_E and Z_E)
Midpoints are the coordinates used in most of the algorithms.
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")
Exploratory Analysis#
Data can be visualised in 3D using the pyvista library. Any Object can be converted to a pyvista object using the to_pyvista method.
df_pv = dh.to_pyvista('Fe_pct')
Using the pyvista library scene creation we can then visualise data in 3D. Here as the data are mostly flat, a vertical exageration is used.
pl = pv.Plotter()
pl.add_mesh(df_pv.tube(radius=10))
pl.set_scale(zscale=20)
pl.show()
Geological section#
scatter function can also be used to view cross section by using the region parameter and provided spatial thresholds in order to define a specific slice.
geo.scatter(
geo_object=dh,
property_x="X_M",
property_y="FROM",
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
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["data"][0]["marker"]["colorbar"] = dict(title = 'Fe_pct')
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#
geo.histogram_plot(data=[{"object": dh, "property": "Fe_pct"}])
Bin number can also be specified.
geo.histogram_plot(data=[{"object": dh, "property": "Al2O3"}], nbins=30)
Multiple histograms can also be shown on the same figure. Here using also the region parameter it is possible to visualise the histogram of the iron values where silica values are lower and higher than 20 %.
geo.histogram_plot(
data=[
{"object": dh, "property": "Fe_pct", "region":"SiO2 < 20"},
{"object": dh, "property": "Fe_pct", "region":"SiO2 >= 20"}
],
nbins=30
)
Export File#
For faster import/export and ease of use, instead of exporting the drillholes into csv, GeoLime has its own format. To export an object, use the to_file method.
dh.to_file("../data/dh_hyper")
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 aspect.
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.