Skip to content

Index

subsurfaceio.logplot

Publication-quality graphical logs (boring / CPT / test-pit).

Compose a template and data payload, then write PDF or HTML:

from subsurfaceio.logplot import LogPlot

LogPlot().load_template('GintBorehole').load_data('B-1').write_pdf('log.pdf')

Modules:

Name Description
render

SVG logplot rendering.

Classes:

Name Description
AxisColumn

Depth or elevation tick axis column.

CPTLogData

SI CPT row plus log-only friction_ratio for plot columns.

Column

One template column: header title, width share, and typed model.

ColumnHeaderStyle

Style for the column-header band above the log body.

ColumnTitle

Label drawn in the column-header band.

Figure

Page geometry and paging for a log plot.

FigureMargins

Figure margins as fractions of page width/height.

GraphicColumn

Hatch/fill graphic column (lithology, sampler, well, etc.).

Header

Metadata header grid below the figure title.

LogPlot

Publication-quality graphical log (SVG → PDF/HTML).

LogPlotData

Payload rendered by a log plot template.

LogPlotMetadata

Well-known scalars for the log title, header, and elevation axes.

LogPlotTemplate

Column layout and page settings for a log plot.

PageState

Current page depth window (meters).

PlotColumn

Continuous parameter plot column (matplotlib → SVG).

PlotGrid

Grid visibility for plot columns.

PlotParameters

Matplotlib line/marker style for a plot series.

PlotSeries

One data series drawn inside a plot column.

SPTLogData

SPT drive row for logplot (depths in m).

SamplesData

Sample interval row for sampler graphic/text columns.

SpecimensData

Lab specimen scalars plotted or labeled on the log.

TextColumn

Interval or point text column.

TextParameters

Typography for text columns.

WellData

Well-construction interval for graphic/text columns.

XAxisLimits

Optional fixed x-axis limits for a plot column.

Attributes:

Name Type Description
Color TypeAlias

CSS/Plotly color string used in plot-column styling.

ColumnModel TypeAlias

Discriminated axis, text, graphic, or plot column model.

ColumnType TypeAlias

Discriminated template column kind.

DEFAULT_LOGPLOT_HEADER_FIELDS tuple[str, ...]
FontWeight TypeAlias

Column-header font weight.

HorizontalAlignment TypeAlias

Horizontal text alignment in a text column.

TitleRotation TypeAlias

Column-header title rotation.

WellPointer TypeAlias

gINT well-construction leader attach point (annulus, center, edge).

Color module-attribute

Color: TypeAlias = PlotlyLiterals.Color

CSS/Plotly color string used in plot-column styling.

ColumnModel module-attribute

ColumnModel: TypeAlias = Annotated[
    AxisColumn | TextColumn | GraphicColumn | PlotColumn,
    Field(discriminator="column_type"),
]

Discriminated axis, text, graphic, or plot column model.

ColumnType module-attribute

ColumnType: TypeAlias = Literal[
    "axis", "text", "graphic", "plot"
]

Discriminated template column kind.

DEFAULT_LOGPLOT_HEADER_FIELDS module-attribute

DEFAULT_LOGPLOT_HEADER_FIELDS: tuple[str, ...] = (
    "project_name",
    "client",
    "location",
    "{easting} / {northing}",
    "test_id",
    "{date_start} / {date_end}",
    "engineer",
    "surface_elevation",
    "water_table",
    "final_depth",
    "method",
    "contractor",
    "crew",
    "remarks",
)

FontWeight module-attribute

FontWeight: TypeAlias = Literal['normal', 'bold']

Column-header font weight.

HorizontalAlignment module-attribute

HorizontalAlignment: TypeAlias = Literal[
    "center", "right", "left"
]

Horizontal text alignment in a text column.

TitleRotation module-attribute

TitleRotation: TypeAlias = Literal["horizontal", "vertical"]

Column-header title rotation.

WellPointer module-attribute

WellPointer: TypeAlias = Literal['A', 'C', 'E']

gINT well-construction leader attach point (annulus, center, edge).

AxisColumn pydantic-model

Bases: BaseModel

Depth or elevation tick axis column.

Elevation mode uses LogPlotMetadata.surface_elevation.

Attributes:

Name Type Description
column_type Literal['axis']

Union tag; must be axis.

as_elevation bool

If True, ticks show elevation instead of depth.

Fields:

as_elevation pydantic-field

as_elevation: bool = False

column_type pydantic-field

column_type: Literal['axis'] = 'axis'

CPTLogData pydantic-model

Bases: CPTData

SI CPT row plus log-only friction_ratio for plot columns.

Fields:

friction_ratio pydantic-field

friction_ratio: NullableFloat = None

Column pydantic-model

Bases: BaseModel

One template column: header title, width share, and typed model.

Attributes:

Name Type Description
title ColumnTitle

Label in the column-header band.

width_ratio float

Share of content width (normalized on the template).

model ColumnModel

Discriminated column model.

Fields:

model pydantic-field

model: ColumnModel

title pydantic-field

title: ColumnTitle

width_ratio pydantic-field

width_ratio: float = 1.0

ColumnHeaderStyle pydantic-model

Bases: BaseModel

Style for the column-header band above the log body.

Attributes:

Name Type Description
size str

Header band height as a percent string (for example '10%').

weight FontWeight

Font weight for column titles.

Fields:

size pydantic-field

size: str = '7.5%'

weight pydantic-field

weight: FontWeight = 'normal'

ColumnTitle pydantic-model

Bases: BaseModel

Label drawn in the column-header band.

Attributes:

Name Type Description
title str

Header text.

rotation TitleRotation

Title rotation.

Fields:

rotation pydantic-field

rotation: TitleRotation = 'horizontal'

title pydantic-field

title: str = ''

Figure pydantic-model

Bases: BaseModel

Page geometry and paging for a log plot.

Attributes:

Name Type Description
title str | None

Figure title; may interpolate metadata field names.

width float

Page width in inches.

height float

Page height in inches.

watermark str | None

Footer watermark, or None.

y_values_per_page int

Depth span (m) covered by one page.

y_top float

Depth (m) at the top of the first page.

Fields:

height pydantic-field

height: float = 11.69

title pydantic-field

title: str | None = None

watermark pydantic-field

watermark: str | None = 'SubSurface.io'

width pydantic-field

width: float = 8.27

y_top pydantic-field

y_top: float = 0.0

y_values_per_page pydantic-field

y_values_per_page: int = 10

FigureMargins pydantic-model

Bases: BaseModel

Figure margins as fractions of page width/height.

Attributes:

Name Type Description
left float

Left margin as a fraction of page width.

right float

Right content edge as a fraction of page width.

top float

Top content edge as a fraction of page height.

bottom float

Bottom margin as a fraction of page height.

Fields:

bottom pydantic-field

bottom: float = 0.05

left pydantic-field

left: float = 0.07

right pydantic-field

right: float = 0.96

top pydantic-field

top: float = 0.96

GraphicColumn pydantic-model

Bases: BaseModel

Hatch/fill graphic column (lithology, sampler, well, etc.).

Attributes:

Name Type Description
column_type Literal['graphic']

Union tag; must be graphic.

data_source str

LogPlotData list attribute to read.

y_top_field str

Top-of-interval field on each row.

y_bottom_field str

Bottom-of-interval field on each row.

color_field str | None

Optional fill-color field.

hatch_field str | None

Optional hatch-key field.

text_field str | None

Optional label field or format template.

pointer_field str | None

Optional well-pointer field (A / C / E).

width_factor float

Hatch strip width as a fraction of the column.

horizontal_borders bool

If True, draw interval boundary lines.

Fields:

color_field pydantic-field

color_field: str | None = None

column_type pydantic-field

column_type: Literal['graphic'] = 'graphic'

data_source pydantic-field

data_source: str = 'strata'

hatch_field pydantic-field

hatch_field: str | None = None

horizontal_borders pydantic-field

horizontal_borders: bool = True

pointer_field pydantic-field

pointer_field: str | None = None

text_field pydantic-field

text_field: str | None = None

width_factor pydantic-field

width_factor: float = 1.0

y_bottom_field pydantic-field

y_bottom_field: str = 'depth'

y_top_field pydantic-field

y_top_field: str = 'depth_top'

Header pydantic-model

Bases: BaseModel

Metadata header grid below the figure title.

fields chooses LogPlotMetadata attributes or {field} templates, in column-major order. Missing values render as - so the grid stays aligned across holes.

Attributes:

Name Type Description
height float

Header band height as a fraction of page height.

nrows int

Number of header rows.

ncols int

Number of header columns.

logo str | None

Logo URL or path, or None for no logo.

fields list[str]

Metadata names or {field} templates in column-major order.

Fields:

Validators:

fields pydantic-field

fields: list[str]

height pydantic-field

height: float = 0.11
logo: str | None = (
    "https://docs.subsurfaceio.app/assets/logo.png"
)

ncols pydantic-field

ncols: int = 2

nrows pydantic-field

nrows: int = 7

validate_fields pydantic-validator

validate_fields() -> Self

LogPlot pydantic-model

Bases: Model

Publication-quality graphical log (SVG → PDF/HTML).

Create with a LogPlotTemplate and LogPlotData, then call write_pdf or write_html.

Attributes:

Name Type Description
template LogPlotTemplate

Column layout and page settings.

data LogPlotData

Rows and metadata rendered by the template.

Fields:

data pydantic-field

data: LogPlotData

layout property

layout: PageLayout

Computed page geometry for the current template.

page_state property

page_state: PageState

Current page depth window.

rendered_pages property

rendered_pages: list[str]

Cached multipage SVG strings (computed on first access).

resolved_title property

resolved_title: str

Figure title with metadata placeholders interpolated when possible.

svg_definitions property

svg_definitions: SVGDefinitions

Shared SVG <defs> bag for the current page render.

template pydantic-field

template: LogPlotTemplate

generate_current_page_svg

generate_current_page_svg() -> str

Render the current page_state as an SVG document string.

Returns:

Type Description
str

Complete SVG document for one page.

generate_pages_svg

generate_pages_svg() -> list[str]

Render all pages covering the inferred depth range.

Returns:

Type Description
list[str]

One SVG string per page. If no depth data is present (or the inferred range yields no pages), returns a single page at y_top=0.

infer_data_ylim

infer_data_ylim() -> Self

Infer depth limits from template column data sources.

Returns:

Type Description
Self

self for chaining.

Raises:

Type Description
ValueError

If a column references an unknown data_source.

load_data

load_data(
    dataset_id: Literal[*available_datasets(),],
) -> Self

Replace data from a bundled dataset and clear page cache.

Parameters:

Name Type Description Default
dataset_id Literal[*available_datasets(),]

Name under datasets/LogPlotData.

required

Returns:

Type Description
Self

self for chaining.

load_template

load_template(
    dataset_id: Literal[*available_datasets(),],
) -> Self

Replace template from a bundled dataset and clear page cache.

Parameters:

Name Type Description Default
dataset_id Literal[*available_datasets(),]

Name under datasets/LogPlotTemplate.

required

Returns:

Type Description
Self

self for chaining.

model_post_init

model_post_init(__context: Any) -> None

set_page_state

set_page_state(y_top: float) -> None

Set the current page depth window from y_top.

Parameters:

Name Type Description Default
y_top float

Depth (m) at the top of the page.

required

write_html

write_html(path: str | Path) -> Path

Write an HTML report with inline SVG pages.

The document title is resolved_title, or Log plot when that is empty.

Opening the HTML in Chrome and using Print → PDF can show uneven letter-spacing on SVG text (Chromium print/hinting). Prefer write_pdf (CairoSVG) for publication PDFs. See TODO.md (logplot).

Parameters:

Name Type Description Default
path str | Path

Output HTML path.

required

Returns:

Type Description
Path

The written path.

write_pdf

write_pdf(path: str | Path) -> Path

Write a multipage PDF of the log.

Parameters:

Name Type Description Default
path str | Path

Output PDF path.

required

Returns:

Type Description
Path

The written path.

LogPlotData pydantic-model

Bases: Model

Payload rendered by a log plot template.

Header and title values live on LogPlotMetadata. LogPlotTemplate header.fields chooses which appear and in what order.

Attributes:

Name Type Description
metadata LogPlotMetadata

Header and title scalars.

strata list[StrataData]

Lithology intervals.

samples list[SamplesData]

Sampler intervals.

specimens list[SpecimensData]

Lab specimen rows.

spt list[SPTLogData]

SPT drive rows.

cpt list[CPTLogData]

CPT rows.

well list[WellData]

Well-construction intervals.

Fields:

cpt pydantic-field

cpt: list[CPTLogData]

metadata pydantic-field

metadata: LogPlotMetadata

samples pydantic-field

samples: list[SamplesData]

specimens pydantic-field

specimens: list[SpecimensData]

spt pydantic-field

spt: list[SPTLogData]

strata pydantic-field

strata: list[StrataData]

well pydantic-field

well: list[WellData]

LogPlotMetadata pydantic-model

Bases: BaseModel

Well-known scalars for the log title, header, and elevation axes.

Config:

  • extra: forbid

Fields:

client pydantic-field

client: str | None = None

contractor pydantic-field

contractor: str | None = None

crew pydantic-field

crew: str | None = None

date_end pydantic-field

date_end: date | None = None

date_start pydantic-field

date_start: date | None = None

easting pydantic-field

easting: NullableFloat = None

engineer pydantic-field

engineer: str | None = None

final_depth pydantic-field

final_depth: NullableFloat = None

location pydantic-field

location: str | None = None

method pydantic-field

method: str | None = None

model_config class-attribute instance-attribute

model_config = ConfigDict(extra='forbid')

northing pydantic-field

northing: NullableFloat = None

project_id pydantic-field

project_id: str | None = None

project_name pydantic-field

project_name: str | None = None

remarks pydantic-field

remarks: str | None = None

rig_model pydantic-field

rig_model: str | None = None

surface_elevation pydantic-field

surface_elevation: NullableFloat = None

test_id pydantic-field

test_id: str | None = None

water_table pydantic-field

water_table: NullableFloat = None

LogPlotTemplate pydantic-model

Bases: Model

Column layout and page settings for a log plot.

Attributes:

Name Type Description
figure Figure

Page geometry and paging.

header Header

Metadata header grid.

column_headers ColumnHeaderStyle

Style for the column-title band.

margins FigureMargins

Figure margins as fractions of page size.

columns list[Column]

Ordered template columns.

Fields:

Validators:

column_headers pydantic-field

column_headers: ColumnHeaderStyle

columns pydantic-field

columns: list[Column]

figure pydantic-field

figure: Figure

header pydantic-field

header: Header

margins pydantic-field

margins: FigureMargins

normalize_width_ratios pydantic-validator

normalize_width_ratios() -> Self

PageState pydantic-model

Bases: BaseModel

Current page depth window (meters).

Attributes:

Name Type Description
y_top float

Depth (m) at the top of the page.

y_bottom float

Depth (m) at the bottom of the page.

Fields:

y_bottom pydantic-field

y_bottom: float

y_top pydantic-field

y_top: float

PlotColumn pydantic-model

Bases: BaseModel

Continuous parameter plot column (matplotlib → SVG).

Attributes:

Name Type Description
column_type Literal['plot']

Union tag; must be plot.

show_legend bool

If True, draw a legend when multiple series exist.

grid PlotGrid

Grid visibility.

x_axis_limits XAxisLimits

Optional fixed x-axis limits.

series list[PlotSeries]

Data series drawn in this column.

Fields:

column_type pydantic-field

column_type: Literal['plot'] = 'plot'

grid pydantic-field

grid: PlotGrid

series pydantic-field

series: list[PlotSeries]

show_legend pydantic-field

show_legend: bool = True

x_axis_limits pydantic-field

x_axis_limits: XAxisLimits

PlotGrid pydantic-model

Bases: BaseModel

Grid visibility for plot columns.

Attributes:

Name Type Description
visible bool

If True, draw the grid.

which Literal['major', 'minor', 'both']

Matplotlib grid which (major, minor, or both).

Fields:

visible pydantic-field

visible: bool = True

which pydantic-field

which: Literal['major', 'minor', 'both'] = 'both'

PlotParameters pydantic-model

Bases: BaseModel

Matplotlib line/marker style for a plot series.

Attributes:

Name Type Description
marker str | None

Matplotlib marker, or None.

color Color | None

Line/marker color.

linewidth float

Line width in points.

fillstyle Literal['full', 'left', 'right', 'bottom', 'top', 'none']

Matplotlib marker fill style.

linestyle Literal['-', '--', '-.', ':', '', 'none']

Matplotlib line style.

drawstyle Literal['default', 'steps', 'steps-pre', 'steps-mid', 'steps-post']

Matplotlib draw style (including steps).

Fields:

  • marker (str | None)
  • color (Color | None)
  • linewidth (float)
  • fillstyle (Literal['full', 'left', 'right', 'bottom', 'top', 'none'])
  • linestyle (Literal['-', '--', '-.', ':', '', 'none'])
  • drawstyle (Literal['default', 'steps', 'steps-pre', 'steps-mid', 'steps-post'])

color pydantic-field

color: Color | None = 'black'

drawstyle pydantic-field

drawstyle: Literal[
    "default",
    "steps",
    "steps-pre",
    "steps-mid",
    "steps-post",
] = "default"

fillstyle pydantic-field

fillstyle: Literal[
    "full", "left", "right", "bottom", "top", "none"
] = "full"

linestyle pydantic-field

linestyle: Literal['-', '--', '-.', ':', '', 'none'] = '-'

linewidth pydantic-field

linewidth: float = 1.0

marker pydantic-field

marker: str | None = None

PlotSeries pydantic-model

Bases: BaseModel

One data series drawn inside a plot column.

Attributes:

Name Type Description
data_source str

LogPlotData list attribute to read.

x_field str

Horizontal data field.

y_field str

Vertical field; typically depth.

parameters PlotParameters

Matplotlib style for this series.

Fields:

data_source pydantic-field

data_source: str

parameters pydantic-field

parameters: PlotParameters

x_field pydantic-field

x_field: str

y_field pydantic-field

y_field: str = 'depth'

SPTLogData pydantic-model

Bases: DepthInterval

SPT drive row for logplot (depths in m).

Fields:

Validators:

blow_count pydantic-field

blow_count: NullableFloat = None

drive_length pydantic-field

drive_length: NullableFloat = None

main_blow_count_1 pydantic-field

main_blow_count_1: NullableFloat = None

main_blow_count_2 pydantic-field

main_blow_count_2: NullableFloat = None

main_blow_count_3 pydantic-field

main_blow_count_3: NullableFloat = None

main_penetration_1 pydantic-field

main_penetration_1: NullableFloat = None

main_penetration_2 pydantic-field

main_penetration_2: NullableFloat = None

main_penetration_3 pydantic-field

main_penetration_3: NullableFloat = None

reported_blow_count pydantic-field

reported_blow_count: str | None = None

seating_blow_count pydantic-field

seating_blow_count: NullableFloat = None

seating_penetration pydantic-field

seating_penetration: NullableFloat = None

compute_reported_blow_count pydantic-validator

compute_reported_blow_count() -> Self

SamplesData pydantic-model

Bases: DepthInterval

Sample interval row for sampler graphic/text columns.

Fields:

drilling_rate_index pydantic-field

drilling_rate_index: NullableFloat = None

fracture_intensity pydantic-field

fracture_intensity: NullableFloat = None

recovery pydantic-field

recovery: float | str | None = None

return_flow pydantic-field

return_flow: NullableFloat = None

rock_quality_designation pydantic-field

rock_quality_designation: NullableFloat = None

sample pydantic-field

sample: str | None = None

sampler_type pydantic-field

sampler_type: SamplerGraphics | None = None

SpecimensData pydantic-model

Bases: DepthInterval

Lab specimen scalars plotted or labeled on the log.

Fields:

bulk_density pydantic-field

bulk_density: NullableFloat = None

dry_density pydantic-field

dry_density: NullableFloat = None

environmental_data pydantic-field

environmental_data: str | None = None

fines_content pydantic-field

fines_content: NullableFloat = None

liquid_limit pydantic-field

liquid_limit: float | str | None = None

percent_passing_no10 pydantic-field

percent_passing_no10: NullableFloat = None

percent_passing_no4 pydantic-field

percent_passing_no4: NullableFloat = None

plastic_limit pydantic-field

plastic_limit: float | str | None = None

plasticity_index pydantic-field

plasticity_index: float | str | None = None

unconfined_compressive_strength pydantic-field

unconfined_compressive_strength: NullableFloat = None

unconfined_compressive_strength_pocket_penetrometer pydantic-field

unconfined_compressive_strength_pocket_penetrometer: (
    NullableFloat
) = None

undrained_shear_strength_torvane pydantic-field

undrained_shear_strength_torvane: NullableFloat = None

unit_weight pydantic-field

unit_weight: NullableFloat = None

water_content pydantic-field

water_content: NullableFloat = None

TextColumn pydantic-model

Bases: BaseModel

Interval or point text column.

Attributes:

Name Type Description
column_type Literal['text']

Union tag; must be text.

data_source str

LogPlotData list attribute to read.

text_field str

Attribute name or str.format template.

y_top_field str

Top-of-interval field on each row.

y_bottom_field str

Bottom-of-interval field on each row.

round_precision int | None

Optional numeric rounding before display.

parameters TextParameters

Typography for this column.

Fields:

column_type pydantic-field

column_type: Literal['text'] = 'text'

data_source pydantic-field

data_source: str

parameters pydantic-field

parameters: TextParameters

round_precision pydantic-field

round_precision: int | None = None

text_field pydantic-field

text_field: str

y_bottom_field pydantic-field

y_bottom_field: str

y_top_field pydantic-field

y_top_field: str

TextParameters pydantic-model

Bases: BaseModel

Typography for text columns.

Attributes:

Name Type Description
font_size float

Font size in points.

horizontal_alignment HorizontalAlignment

Horizontal text alignment.

Fields:

font_size pydantic-field

font_size: float = 7.0

horizontal_alignment pydantic-field

horizontal_alignment: HorizontalAlignment = 'left'

WellData pydantic-model

Bases: DepthInterval

Well-construction interval for graphic/text columns.

Fields:

hatch pydantic-field

hatch: WellGraphics | None = None

pointer pydantic-field

pointer: WellPointer | None = None

text pydantic-field

text: str | None = None

XAxisLimits pydantic-model

Bases: BaseModel

Optional fixed x-axis limits for a plot column.

Attributes:

Name Type Description
left NullableFloat

Lower x-limit, or None to autoscale.

right NullableFloat

Upper x-limit, or None to autoscale.

Fields:

left pydantic-field

left: NullableFloat = None

right pydantic-field

right: NullableFloat = None