Skip to content

plot3d

3D scenes of drill holes, points, meshes and block models, drawn in the browser by a bundled three.js viewer.

A Scene shows as a widget in Jupyter, Colab and VS Code (pip install 'boitata[3d]'), or as a self-contained HTML page opened in the web browser; Scene.screenshot renders it to a PNG in headless Chromium (pip install 'boitata[export]'). Building, saving and showing a scene needs numpy only.

Scene

Scene(*, theme='auto', height=600, motion_quality='auto')

3D scene of drill holes, points, meshes and block models, drawn by a three.js viewer.

Layers colored by the same variable share its color map, range and color bar. Null values are never drawn: a row null in the column that colors its layer is left out, and nulls never enter a color range.

Parameters:

Name Type Description Default
theme (auto, light, dark)

Colors of the background, box, grid, labels, panel and color bars, and of layers drawn in no color of their own. "auto" follows the page hosting the viewer (JupyterLab, VS Code, the documentation) or else the system preference, and switches with it. A dict overrides keys of a built-in theme: base ("auto", "light" or "dark", default "auto") and CSS colors for background, panel, raised, border, text, muted, grid, box, accent, layer and halo (the thin outline that keeps screen-size lines and points readable on any background).

"auto"
height int

Height of the viewer in a notebook, in pixels; a saved page fills the browser window.

600
motion_quality (auto, full)

What draws while the camera moves; the full scene draws again about 150 ms after it stops. "full" draws everything. A number in (0, 1] draws about that share of each layer's instances (blocks, segments, points; surfaces stay whole), an evenly spread subset that keeps each layer's shape, at a resolution lowered to match. "auto" starts from what the scene's size suggests and adapts to the measured frame time. The panel's Quality control switches between the three while viewing.

"auto"

filters property

filters

Filters of the layers, as conditions by column: {layer name: {column: (low, high) or [categories]}}.

Layers without a filter are left out. In a notebook it follows the panel's edits in the last widget shown; a saved page has no way back, so there it holds what add and this property set. Setting it replaces every layer's filter, with conditions as add takes them, and updates the widgets shown.

Returns:

Type Description
dict

motion_quality property

motion_quality

What draws while the camera moves: "auto", "full" or a share of each layer's instances.

Setting it validates the value as Scene does and applies to widgets displayed and pages saved afterwards.

Returns:

Type Description
str or float

picked property

picked

The row last clicked in the viewer, or None.

A click on a drawn element picks it: a card beside it lists every column sent for its row, its real-world coordinates, the hole and depths of a drill-hole interval and the size of a block, and the element is outlined in the theme's accent. Esc, the card's close button or a click on empty space dismiss it; a drag never picks, and neither does what the filter or the section hides. The pick reads {"layer": name, "row": index, "values": {column: value}, "position": (x, y, z)}. row indexes the layer's rows: points, blocks, drill-hole intervals (segments between survey stations for holes without intervals) or mesh triangles, whose vertex columns are read at the corner nearest the click. values holds the columns sent to the viewer, None for nulls, numbers to the 7 significant digits the viewer keeps. position is the point, block center, interval middle or the point clicked on a mesh.

It follows the widgets shown in a notebook; without one, before a click and once dismissed it is None.

Returns:

Type Description
dict or None

sections property

sections

The section, as {"points": [(x, y, z), ...], "width": w, "dip": d, "unfolded": bool}, or None.

Points are real-world vertices, at the elevation the section hinges on; width is None for the default until the viewer settles it. In a notebook it follows the cuts, edits and unfolding made in the last widget shown; a saved page has no way back, so there it holds what section and this property set. Setting it takes such a dict (points required, the other keys optional, as in section) or None, and updates the widgets shown.

Returns:

Type Description
dict or None

add

add(
    data,
    values=None,
    *,
    name=None,
    representation=None,
    color=None,
    opacity=1.0,
    cmap=None,
    clim=None,
    point_size=None,
    line_width=None,
    radius=None,
    label=None,
    visible=True,
    columns=None,
    filter=None,
    contour_step=None,
    scheme=None,
)

Adds a layer.

Each kind of data draws in one of a few representations, the first being the default, and the panel switches between them while viewing, keeping the layer's colors, range, opacity and visibility:

  • drill holes: "lines" of a fixed screen width, one segment per interval split at the survey stations so it follows the trace; "tubes", shaded cylinders along the same segments; "points" at the middle of each interval.
  • block models: "cells", boxes along the model's rotated axes, sub-blocks at their own size; "wireframe", the block edges (opaque, only the edges in sight; below opacity 1, every edge); "points" at the block centers.
  • meshes: "surface"; "wireframe", the triangle edges; "points" at the vertices.
  • point sets: "points", round points of a fixed screen size; "spheres", shaded spheres.

Lines and screen-size points carry a thin outline in the theme's halo color, so dark and light marks stay readable on either background; their own colors are exact.

Parameters:

Name Type Description Default
data (PointSet, Drillholes, BlockModel or Mesh)

What to draw. Drill holes take their interval columns, or the hole name without intervals; a mesh its vertex and face attributes.

required
values str

Column that colors the layer; its null rows are not drawn. Numbers map through cmap, text takes one color per category. Without it the layer is drawn in color.

None
name str

Name in the layer panel; default the kind and a number, e.g. "block model 1".

None
representation str

How the layer draws, one of its kind's representations above; default the first.

None
color str

CSS color of the layer when not colored by a column; default the theme's layer color.

None
opacity float

From 0 (invisible) to 1 (opaque).

1.0
cmap str

Color map of values for every layer it colors: "viridis" (default), "magma", "inferno", "plasma", "cividis" or "turbo".

None
clim tuple of float

(low, high) range of values for every layer it colors; default the range of their valid values.

None
point_size float

Diameter of screen-size points, in pixels; default 6.

None
line_width float

Width of lines and wireframe edges, in pixels; default 2.5 for drill holes, 1 for wireframes.

None
radius float

Radius of drill-hole tubes and of spheres, in the data's length unit; default 1/400 of the diagonal of the holes' bounds for tubes, 1/250 of the points' for spheres.

None
label str

Title of the color bar of values; default the column name.

None
visible bool

Whether the layer starts shown; the panel toggles it.

True
columns sequence of str

Columns sent to the viewer, which offers them to color by and shows them for a clicked row; default every numeric and text column. values and the hole name of drill holes are always sent.

None
filter dict

Rows shown from the start, as conditions on columns sent to the viewer, all of which a row must meet: a (low, high) tuple for a number column, inclusive, None leaving that end open; a list of the categories kept for a text column. A row null in a filtered column fails its condition. At most four columns; the layer's filter panel edits them while viewing, and filters reads them back. For example {"p_above_5": (50, None), "LENS": ["lens_1", "lens_2"]}.

None
contour_step float

Draws isolines of values on the face a section cuts through this block model, spaced contour_step apart in the column's own units. Needs values to be numeric and the model to be regular (one size for every block; call to_regular() first otherwise). The lines are fixed to this column: they do not follow a later change of which column colors the layer in the viewer panel. No effect without an active section.

None
scheme Categories

Order and colors of a text values: the legend and the layer's colors follow scheme.names and scheme.colors instead of the column's own sorted categories and the built-in palette. Values not in the scheme are not drawn, unless it has an other bucket. Describes values; pass values too.

None

Returns:

Type Description
Scene

This scene, to chain calls.

view

view(*, azimuth=45.0, dip=30.0)

Sets the direction the camera looks along; the view still frames every shown layer.

It replaces the camera a widget last reported, so screenshots look along it until the view is moved again.

Parameters:

Name Type Description Default
azimuth float

Bearing of the line of sight, in degrees clockwise from north.

45.0
dip float

Angle of the line of sight below horizontal, in degrees: 0 looks level, 90 straight down (a plan with north up).

30.0

Returns:

Type Description
Scene

This scene, to chain calls.

section

section(points, *, width=None, dip=90.0)

Cuts every layer to a slab around a section, or removes the section with section(None).

The section runs along a polyline in plan: each segment's surface passes through it and dips dip degrees to the right of the direction the points run in (reverse them to dip the other way). Whatever lies more than width / 2 from that surface, or beyond the polyline's ends, is not drawn, in every layer and representation: blocks are cut and capped with faces of their own color, meshes are cut and outlined in the theme's accent where the slab's faces cross them, and drill-hole intervals, points and spheres show whole when their middle lies in the slab. Filters still apply. The section's trace and slab edges are drawn in the accent along the top of the box, which shrinks to the section.

While viewing, Shift-drag across the view cuts a straight section under the swept line, its ends picked on the level plane through the middle of the shown layers (or, in views within 20 degrees of level, on the upright plane through it that faces the camera); S or the draw button switches to a plan view where clicks add the vertices of a polyline, Shift locks a segment to a multiple of 45 degrees, Backspace removes the last vertex, Enter or the button cuts and Esc cancels. The mouse wheel zooms; Shift+wheel sets the width while cutting or drawing, or of the section shown. U or the unfold button lays the section out flat, with the distance along it on the bottom axis and elevation up, and folds it back; X or the clear button removes it. sections reads the result back.

Parameters:

Name Type Description Default
points array_like or None

(n, 2) or (n, 3) vertices in real-world coordinates, 2 <= n <= 17 distinct in plan; None removes the section. A dipping section hinges on the mean elevation of (x, y, z) vertices, or on the middle of the scene for (x, y) ones.

required
width float

Thickness of the slab kept around the section, in the data's length unit; default 1/20 of the diagonal of the shown layers' bounds, or the width last set while viewing.

None
dip float

Dip of the section's surface in degrees, in (0, 90]; 90 is upright.

90.0

Returns:

Type Description
Scene

This scene, to chain calls.

save

save(path)

Writes the scene to a self-contained HTML page: the viewer and the data inlined, nothing fetched.

The page opens on the view a notebook widget of the scene last showed (camera, layer settings, view toggles), if any, and fills the browser window.

Parameters:

Name Type Description Default
path str or Path

HTML file to write.

required

Returns:

Type Description
Path

show

show()

Displays the scene in Jupyter, or else saves it to a temporary page and opens it in the web browser.

Returns:

Type Description
Path or None

The page opened in the browser; None in Jupyter.

screenshot

screenshot(
    path, *, scale=1, panel=False, transparent=False
)

Writes a PNG image of the scene, with its color bars, axis labels and orientation gizmo.

The scene renders in headless Chromium and the file is written on return, in a script as in a notebook. Once a notebook widget of the scene has been shown, the image reproduces the widget as it last stood: its size, camera, theme, layer settings, view toggles, filters and section (folded or unfolded), as the widget reports them a moment after each change; view sets a new direction. Otherwise the view is the scene's, height pixels high and 1.6 times as wide. That needs Playwright, pip install 'boitata[export]', which downloads Chromium on first use.

Parameters:

Name Type Description Default
path str or Path

PNG file to write.

required
scale float

Pixels per CSS pixel of the viewer, in (0, 8]; 2 doubles the width and height.

1
panel bool

Whether the layer panel shows in the image.

False
transparent bool

Whether the background is transparent instead of the theme's.

False

Returns:

Type Description
Path

BlockModel

Regular or masked grid of blocks, 2D or 3D, optionally rotated.

bounds property

bounds

(min, max) corners, None without rows.

column_names property

column_names

Names of the attribute columns.

coords property

coords

(n, 3) cell centers in world coordinates.

corners property

corners

(n, 8, 3) world-space corners of each row's box: vertex c (0..8) takes the row's minimum extent on axis a if bit a of c is 0, its maximum if 1.

extents property

extents

(n, 6) sub-block extents as fractions of the parent cell [u0, v0, w0, u1, v1, w1], or None when not sub-blocked.

index property

index

Parent cell index of each row (masked or sub-blocked), or None when regular.

length_unit property

length_unit

Unit of the coordinates, such as m or ft; None when not declared.

units property

units

Units of the attributes that have one; see Table.units.

volumes property

volumes

Volume of each row (area with unit height in 2D).

x property

x

x of each row's coordinates.

y property

y

y of each row's coordinates.

z property

z

z of each row's coordinates.

convert_units method descriptor

convert_units(column, *, to)

New model with column converted to unit to; see Table.convert_units.

discretize method descriptor

discretize(n)

Nodes discretizing every block, e.g. targets for simulate(blocks=).

Parameters:

Name Type Description Default
n int or sequence of int

Nodes per axis inside each block; an int applies to x, y and z, or to x and y only in a 2D model.

required

Returns:

Type Description
BlockModel

A masked grid n times finer, or for a sub-blocked model each sub-block split into n per axis. Its one column, block, is the row in this model of each node.

drop_null

drop_null(*columns)

Rows with a value in every one of columns, all columns by default.

filter method descriptor

filter(mask)

Rows where mask is true; the result is masked.

from_extents staticmethod

from_extents(
    *objects,
    size,
    buffer=Ellipsis,
    rotation=None,
    snap=Ellipsis,
    crs=None,
    length_unit=None,
)

Smallest regular grid holding every object plus a buffer.

Parameters:

Name Type Description Default
*objects (PointSet, Drillholes, Mesh, Polylines, BlockModel or array_like)

What the grid must cover: points, drill hole paths, mesh or line vertices, the corners of another grid, or (n, 2)/(n, 3) coordinates.

required
size sequence of float

(dx, dy, dz) block size. With (dx, dy) or dz=None the grid is 2D: one layer spanning the buffered z range.

required
buffer float or sequence of float

Margin added on each side, one value or one per grid axis.

0.0
rotation tuple of float

Azimuth, dip and rake in degrees; the extents are measured along the rotated grid axes.

None
snap bool, float or sequence of float

Put the origin on a multiple of this step, measured along the grid axes, so grids built from different data line up; True snaps to the block size.

False
crs str
None

Returns:

Type Description
BlockModel

A regular model without attributes, with the fewest blocks along each axis that hold every point.

from_meshes staticmethod

from_meshes(
    origin,
    size,
    count,
    meshes,
    subgrid,
    *,
    rotation=Ellipsis,
    column="domain",
    fill=None,
    crs=None,
    length_unit=None,
)

Sub-blocked model of the grid origin, size, count and rotation from prioritized meshes; see subblock.

grid

grid(column)

column (a name or one value per row) on the full grid as an (nz, ny, nx) array, NaN (None for text) in absent cells; for regular and masked models.

regularize method descriptor

regularize(target, *, min_fraction=0.0)

Columns of this model averaged onto the blocks of target.

Each row of this model counts in a target block by the volume they share, from exact box overlaps, so it works both ways between regular, masked and sub-blocked models: to a coarser grid, sub-blocks to their parents, or a regular estimate onto sub-blocks.

Parameters:

Name Type Description Default
target BlockModel

Blocks to average onto, with the same rotation (the origin and sizes may differ). Its own columns are kept.

required
min_fraction float

Blocks less covered than this are null.

0.0

Returns:

Type Description
BlockModel

target with every column of this model: floats as volume-weighted means of the non-null rows, other columns (text, integers) as the value filling the most volume, ties to the smallest, nulls not voting. fraction is the share of each block covered by this model, so volumes * fraction * grade sums to this model's volumes * grade.

row_at method descriptor

row_at(points)

Row holding each point.

Parameters:

Name Type Description Default
points array_like

(n, 3) or (n, 2) world coordinates.

required

Returns:

Type Description
ndarray

int64 row of each point, -1 outside the model or in a missing block.

sample

sample(points, column)

Value of column (a name or one value per row) at each point; NaN, or None for text, outside the model or in a missing block.

subblock method descriptor

subblock(meshes, subgrid, *, column='domain', fill=None)

Sub-blocks every block by prioritized meshes.

Each block is split on a regular subgrid; each sub-cell takes the label of the first domain holding its center. Blocks of one label stay whole, others keep runs of sub-cells merged along x, then y.

Parameters:

Name Type Description Default
meshes sequence of (Mesh or Polylines, str, str)

(mesh, rule, label) in priority order, the first match winning. rule is "inside" a closed mesh, or "below" or "above" a surface such as topography, along world z; off the surface's footprint neither matches. Polylines take "inside" only: the vertical prism over their features, as Polylines.contains.

required
subgrid int or sequence of int

Sub-cells per axis, which sets the smallest sub-block; an int applies to x, y and z, or to x and y only in a 2D model.

required
column str

Name of the label column.

"domain"
fill str

Label of the sub-cells no domain holds; without it they are dropped.

None

Returns:

Type Description
BlockModel

Sub-blocked model on subgrid with the label column and the columns of each sub-block's parent block.

subblocked staticmethod

subblocked(
    origin,
    size,
    count,
    parent,
    extents,
    *,
    rotation=Ellipsis,
    subgrid=None,
    attributes=None,
    crs=None,
    length_unit=None,
)

Sub-blocked model: parent cell of each sub-block (sorted) and its (n, 6) extent as fractions of that cell; subgrid (e.g. (4, 4, 8)) requires corners on that subdivision.

to_length_unit method descriptor

to_length_unit(unit, *, crs=None)

A copy with the coordinates converted to unit, the new length unit.

Parameters:

Name Type Description Default
unit str

A length unit, such as m or ft.

required
crs str

The CRS of the converted coordinates; required when the coordinates have a CRS, which a change of unit changes.

None

Raises:

Type Description
InvalidInput

Without a length unit to convert from, or with a CRS and no crs.

to_regular method descriptor

to_regular()

Every parent cell, absent cells null. Sub-blocks merge into their parent as in regularize, without the fraction column: floats as volume-weighted means, other columns by volume majority.

to_table method descriptor

to_table()

Attributes preceded by centroid x, y, z.

with_attributes method descriptor

with_attributes(table)

New model with table as the attributes, one row per block.

with_column method descriptor

with_column(name, values, *, unit=None)

New model with the attribute name added or replaced: numbers (NaN is null) or text (None is null). The column takes unit, or else the unit values carries.

with_columns method descriptor

with_columns(data)

New model with the columns of data, a dict or table, added or replaced.

with_units method descriptor

with_units(units)

New model with the units of units, column name to unit; None removes one.

Categories

Named categories with integer codes: a code is the index of its name.

Parameters:

Name Type Description Default
names sequence of str

Category names in code order.

required
colors sequence of str

One matplotlib color per name; None picks them at plot time.

required
mapping dict

Raw label to name, many to one.

required
other str

Name that unlisted labels fall into; appended when not listed, and always the last code.

required

decode method descriptor

decode(codes)

Name of each code; None for NaN.

encode method descriptor

encode(values)

Code of each value as float64, NaN for null. 1, 1.0 and "1" are one label. An unlisted label goes to other, else raises InvalidInput naming it and its row count.

from_json staticmethod

from_json(text)

Reads to_json output; raises InvalidInput on another class's JSON or a newer format.

from_values staticmethod

from_values(
    values,
    *,
    weights=None,
    min_share=0.0,
    mapping=None,
    other="other",
    colors=None,
)

Categories of observed values.

mapping is applied first; the distinct names are then sorted, numerically when all are integers. Names whose weighted share is below min_share are lumped into other, the last code, and recorded in mapping; other exists only when something was lumped. Integral floats are integer labels (1.0 is "1"); None and NaN are skipped. The result does not depend on row order.

lump method descriptor

lump(names, *, into='other')

New categories with names merged into into: a listed name, else other when there is none, else a new name before other. The merged names become mapping entries.

shares method descriptor

shares(codes, *, weights=None)

Weighted proportion of each code, nulls skipped.

Drillholes

Collar, survey and interval tables desurveyed by method: "minimum_curvature" (circular arcs), "tangential" (each survey's direction holds down to the next) or "balanced_tangential" (half of each segment along each end's direction). Survey angles are azimuth (clockwise from north) and either dip (degrees below horizontal) or inclination (degrees from vertical); holes without survey are vertical.

bounds property

bounds

(min, max) corners of the desurveyed holes, None without stations.

column_names property

column_names

Names of the interval columns.

coords property

coords

(n, 3) interval midpoints.

interval_columns property

interval_columns

Hole, from and to column names of the interval table, if one was given.

length_unit property

length_unit

Unit of the coordinates and depths, such as m or ft; None when not declared.

x property

x

x of each row's coordinates.

y property

y

y of each row's coordinates.

z property

z

z of each row's coordinates.

at method descriptor

at(holes, depths)

(n, 3) positions at measured depths down holes, e.g. contacts.

composite method descriptor

composite(
    length,
    grades,
    *,
    domain=None,
    intervals=None,
    residual="keep",
    min_fraction=0.5,
    categories=Ellipsis,
)

Length-weighted composites, never crossing a change of domain and located at their midpoints. Composites with none of the grades sampled are dropped. Each grade comes with its sampled length, <grade>_length, so the sum of grade × <grade>_length equals the input metal; length also counts unsampled ground. The hole column keeps its constructor name, followed by from, to and length.

Parameters:

Name Type Description Default
length (float, str or None)

Composite length in the length unit of the holes, or text such as "2 m"; None gives one composite per run of domain.

required
grades sequence of str

Numeric columns, averaged over the length that carries a value.

required
domain str

Column whose changes composites never cross.

None
intervals table

Hole, from and to columns (named as in the constructor) of non-overlapping intervals to composite to instead of length, e.g. benches; ground outside them is left out.

None
residual (keep, drop, merge)

What to do with the tail of a run shorter than min_fraction * length; merge adds it to the previous composite of the run, if there is one.

"keep"
min_fraction float

Tail length, as a fraction of length, below which residual applies.

0.5
categories sequence of str

Categorical columns, composited to the value covering the most length.

Ellipsis

from_tables

from_tables(tables, *, intervals='assays', **options)

Drillholes from a mapping with collars and surveys tables, plus the intervals table (None for none), as the datasets return them; options go to the constructor.

mesh_intervals method descriptor

mesh_intervals(mesh, *, step=1.0, tolerance=0.01)

Splits each hole's path against a closed mesh, wherever it crosses the surface.

The path is sampled every step of depth and a crossing between two samples is bisected down to tolerance; a boundary crossed more than once within one step is missed. Every depth down every hole falls in exactly one row, so piping the result through merge_intervals splits assays exactly at the mesh instead of at a logged contact.

Parameters:

Name Type Description Default
mesh Mesh

A closed mesh.

required
step float

Sampling step down each hole, in meters.

1.0
tolerance float

Depth tolerance the crossing is refined to, in meters.

0.01

Returns:

Type Description
Table

Hole (named as in the constructor), FROM, TO and INSIDE (whether the run is inside mesh), one row per run down each hole — matching merge_intervals's own column names.

paths method descriptor

paths()

Desurveyed stations: hole (named as in the constructor), depth, x, y, z.

runs method descriptor

runs(
    grade,
    *,
    cutoff=None,
    category=None,
    ore=Ellipsis,
    min_length=Ellipsis,
    max_dilution=Ellipsis,
    edge=Ellipsis,
)

Ore and waste runs down each hole: contiguous intervals above cutoff (or of an ore category), cleaned by mining rules. The runs of a hole partition its samples, so Σ grade × length equals the sample metal.

Rules apply in order: internal dilution, then edge dilution, then minimum length. Samples missing the grade are left out, as unsampled ground, and samples missing the category are waste; like composite(None, ...), gaps are skipped, not bridged.

Parameters:

Name Type Description Default
grade str or None

Numeric column; None with category for runs without grades.

required
cutoff float

Samples at or above it are ore, unless category is given; also the grade a run must keep when it takes in internal dilution.

None
category str

Column whose values in ore flag ore samples.

None
ore sequence of str

Ore values of category.

Ellipsis
min_length float

Runs spanning less, shortest first, take their neighbors' flag and merge with them.

Ellipsis
max_dilution float

Waste runs between ore spanning at most this are taken into the ore when the grade of the three together stays at or above cutoff.

Ellipsis
edge float

Waste taken into each ore run on each side where it meets waste.

Ellipsis

Returns:

Type Description
Table

Hole (named as in the constructor), from, to, length (sampled length), the grade, and ore, one row per run down each hole.

samples method descriptor

samples()

Interval midpoints with every interval column; intervals of holes without a collar are dropped.

Mesh

Triangulated surface or solid with per-vertex and per-face attributes.

bounds property

bounds

(min, max) corners of the bounding box, None when empty.

column_names property

column_names

Names of the vertex columns, then the face columns.

coords property

coords

(n, 3) vertices.

is_closed property

is_closed

Every edge shared by exactly two non-degenerate triangles.

length_unit property

length_unit

Unit of the coordinates, such as m or ft; None when not declared.

volume property

volume

Enclosed volume of a closed mesh, positive when wound outward.

x property

x

x of each row's coordinates.

y property

y

y of each row's coordinates.

z property

z

z of each row's coordinates.

contains method descriptor

contains(points)

Whether each point is inside, by generalized winding number.

distance method descriptor

distance(points, *, signed=False)

Distance to the surface; signed makes inside points negative.

fill_holes method descriptor

fill_holes()

Closes each hole with a fan of triangles from its first vertex.

Returns:

Type Description
Mesh

A new mesh with the fans appended, wound like the faces around each hole, with null face attributes. A hole is a loop of boundary edges; a loop through a vertex that starts two boundary edges stays open. A fan suits small, nearly planar, convex holes; others can come out folded, so validate the result.

proportion method descriptor

proportion(targets, *, size=None, discretization=Ellipsis)

Proportion of each block inside, from a grid of points per block where the surface may cut it: discretization per axis, or one count for all three. targets is a BlockModel, whose rotation and sub-block extents count, or axis-aligned centroids with a shared size.

repair method descriptor

repair(*, tolerance=0.0)

Weld close vertices, drop degenerate and duplicate triangles, and wind the triangles consistently.

Parameters:

Name Type Description Default
tolerance float

Vertices within this distance of an earlier vertex merge into it; 0 merges exact duplicates only.

0.0

Returns:

Type Description
Mesh

A new mesh without unused vertices, each connected piece wound one way. A closed piece inside an even number of other closed pieces winds outward; inside an odd number it is a cavity and winds inward, so the volume is outer minus cavities. Kept vertices and triangles keep their order and attributes. Repairing it again changes nothing. Crossing faces stay; validate reports them.

to_length_unit method descriptor

to_length_unit(unit, *, crs=None)

A copy with the coordinates converted to unit, the new length unit.

Parameters:

Name Type Description Default
unit str

A length unit, such as m or ft.

required
crs str

The CRS of the converted coordinates; required when the coordinates have a CRS, which a change of unit changes.

None

Raises:

Type Description
InvalidInput

Without a length unit to convert from, or with a CRS and no crs.

validate method descriptor

validate(*, tolerance=0.0)

Everything that keeps the mesh from being a clean closed solid.

Parameters:

Name Type Description Default
tolerance float

A vertex within this distance of an earlier vertex is a duplicate; 0 finds exact duplicates only.

0.0

Returns:

Type Description
MeshReport

Counts in summary and one row per problem in problems. Degenerate faces are left out of the edge, vertex and shell checks.

vertical_distance method descriptor

vertical_distance(points)

Signed vertical distance to a surface such as topography.

Parameters:

Name Type Description Default
points (array_like, PointSet or BlockModel)

(n, 3) points, or the centroids of a point set or block model. Rows with a NaN coordinate are allowed.

required

Returns:

Type Description
ndarray

Point elevation minus surface elevation at the same (x, y): positive above, negative below. NaN where a coordinate is NaN or no triangle covers the point in plan; where the surface overlaps itself, the highest counts.

with_face_column method descriptor

with_face_column(name, values)

New mesh with the per-triangle attribute name added or replaced.

with_vertex_column method descriptor

with_vertex_column(name, values)

New mesh with the per-vertex attribute name added or replaced.

PointSet

Scattered samples: coordinates plus an attribute table.

bounds property

bounds

(min, max) corners, None when empty.

column_names property

column_names

Names of the attribute columns.

coords property

coords

(n, 3) coordinates.

length_unit property

length_unit

Unit of the coordinates, such as m or ft; None when not declared.

units property

units

Units of the attributes that have one; see Table.units.

x property

x

x of each row's coordinates.

y property

y

y of each row's coordinates.

z property

z

z of each row's coordinates.

convert_units method descriptor

convert_units(column, *, to)

New point set with column converted to unit to; see Table.convert_units.

drop_null

drop_null(*columns)

Rows with a value in every one of columns, all columns by default.

filter method descriptor

filter(mask)

Points where mask is true.

from_table staticmethod

from_table(
    table,
    *,
    x="X",
    y="Y",
    z=None,
    crs=None,
    length_unit=None,
)

Splits coordinate columns out of an Arrow-compatible table.

to_length_unit method descriptor

to_length_unit(unit, *, crs=None)

A copy with the coordinates converted to unit, the new length unit.

Parameters:

Name Type Description Default
unit str

A length unit, such as m or ft.

required
crs str

The CRS of the converted coordinates; required when the coordinates have a CRS, which a change of unit changes.

None

Raises:

Type Description
InvalidInput

Without a length unit to convert from, or with a CRS and no crs.

to_table method descriptor

to_table()

Attributes preceded by x, y, z.

with_attributes method descriptor

with_attributes(table)

New point set with table as the attributes, one row per point.

with_column method descriptor

with_column(name, values, *, unit=None)

New point set with the attribute name added or replaced: numbers (NaN is null) or text (None is null). The column takes unit, or else the unit values carries.

with_columns method descriptor

with_columns(data)

New point set with the columns of data, a dict or table, added or replaced.

with_units method descriptor

with_units(units)

New point set with the units of units, column name to unit; None removes one.

plot

plot(
    data, values=None, *, theme="auto", height=600, **kwargs
)

Draws one container in a new scene: Scene(theme=theme, height=height).add(data, values, **kwargs).

Parameters:

Name Type Description Default
data (PointSet, Drillholes, BlockModel or Mesh)

What to draw.

required
values str

Column that colors it, as in Scene.add.

None
theme (auto, light, dark)

Colors of the scene, as in Scene.

"auto"
height int

Height of the viewer in a notebook, in pixels.

600
**kwargs

Other keywords of Scene.add: name, representation, color, opacity, cmap, clim, point_size, line_width, radius, label, visible, columns and filter.

required

Returns:

Type Description
Scene

The new scene; it displays in a notebook as the last expression of a cell, Scene.show opens it anywhere.

Examples:

>>> import boitata as bt
>>> points = bt.PointSet([[0.0, 0.0, 0.0], [10.0, 5.0, 2.0]], {"zn": [1.5, 4.0]})
>>> bt.plot3d.plot(points, "zn", representation="spheres")
Scene(1 layers)

used in