Getting started
cpt-anywidget is a set of anywidget viewers for cone penetration tests (CPTs) and geotechnical borehole logs. The viewers accept CPT data from any source: if you can load it into Python, you can plot it. The viewers work in marimo and Jupyter notebooks. All viewers share one zoomable vertical axis. The axis shows depth below surface, or elevation in m NAP.
The package contains three viewers:
CPTViewershows one CPT: measurement channels, interpretation columns, a nearby borehole log, and an editable layer column.ProfileViewershows many CPTs side by side along a profile line (a cross-section).BoreholeViewershows one geotechnical borehole log with soil-composition bands.
Requirements
Section titled “Requirements”- Python 3.10 or newer.
- A notebook environment: marimo, Jupyter, or another anywidget host.
Install
Section titled “Install”The package is not on PyPI yet. Install it from git:
uv add "cpt-anywidget @ git+https://github.com/bedrock-engineer/cpt-anywidget"The bro extra installs brodata:
uv add "cpt-anywidget[bro] @ git+https://github.com/bedrock-engineer/cpt-anywidget"Only layers_from_bhrgt and layers_from_bore need the bro extra.
The viewers do not need it.
Show a first CPT
Section titled “Show a first CPT”Put this code in a notebook cell:
import polars as plfrom cpt_anywidget import CPTViewer
df = pl.DataFrame({ "depth": [0.0, 0.02, 0.04], # m below surface "coneResistance": [0.1, 0.4, 0.9], # MPa "localFriction": [0.01, 0.02, 0.02],})
CPTViewer(df, vertical="depth", channels=["coneResistance", "localFriction"])The notebook shows the widget when the cell returns it. The widget plots each channel against the shared vertical axis.
Prepare the data
Section titled “Prepare the data”The data argument takes
tidy
columns: a polars or pandas DataFrame, or a dict of equal-length lists.
Each row is one depth sample. Each column is one measurement.
The widget does not parse file formats. The widget does not convert
units. Use a reader to do that upstream — any reader works. Examples:
brodata for Dutch
BRO data,
pygef for GEF files,
python-ags4 for AGS files, or
plain polars.read_csv for a CSV.
Column names are free. The BRO column names get built-in labels, units,
and colors:
coneResistance, localFriction, frictionRatio, porePressureU1,
porePressureU2, and inclination. For a column with a different name,
pass a Channel
binding:
from cpt_anywidget import Channel
CPTViewer(df, channels=[Channel("qn", label="qn", unit="MPa", color="tomato")])Select the vertical coordinate
Section titled “Select the vertical coordinate”Set vertical to the column that holds the vertical coordinate:
"depth"is depth below surface, in m, positive down."nap"is elevation in m NAP, positive up. Compute it as the surface elevation minus the depth.
For a different datum, pass a
Vertical binding.
Use the viewer
Section titled “Use the viewer”- To zoom the vertical axis, hold the Ctrl key (Cmd on macOS) and turn the mouse wheel. A trackpad pinch also zooms.
- To pan a zoomed axis, drag in the plot area.
- To zoom to a range, hold the Shift key and drag along the axis.
- To reset the zoom, double-click in the plot area.
- To read the values at a depth, move the pointer across the plot.
The mouse wheel without a modifier key scrolls the notebook, not the chart.
Next steps
Section titled “Next steps”CPTViewerreference — all traits: annotations, overlays, interpretations, the borehole column, and the editable layer column.ProfileViewerreference — build a cross-section from many CPTs.BoreholeViewerreference — show a borehole log from any source, with converters for BRO BHR-GT and GEF files.- Data intake reference — the
exact data contract, and the
tidyandsplithelpers.