Tutorial about computing hulls for localization data#

For each set of localizations with 2D or 3D spatial coordinates various hull can be computed. A hull can be the minimal bounding box, the oriented minimal bounding box, the convex hull, or an alpha shape.

You can trigger computation of specific hull objects using a specific hull class or from the corresponding LocData attribute.

from pathlib import Path

%matplotlib inline

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import locan as lc
from locan.data.hulls import BoundingBox, ConvexHull, OrientedBoundingBox
/tmp/ipykernel_1512/1272412987.py:6: DeprecationWarning: 
Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0),
(to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries)
but was not found to be installed on your system.
If this would cause problems for you,
please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466
        
  import pandas as pd
Jupyter environment detected. Enabling Open3D WebVisualizer.
[Open3D INFO] WebRTC GUI backend enabled.
[Open3D INFO] WebRTCWindowSystem: HTTP handshake server disabled.
lc.show_versions(system=False, dependencies=False, verbose=False)
Locan:
   version: 0.20.0.dev41+g755b969

Python:
   version: 3.11.6

Synthetic data#

rng = np.random.default_rng(seed=1)
locdata = lc.simulate_Thomas(parent_intensity=1e-3, region=((0, 100), (0, 100)), cluster_mu=10, cluster_std=2, seed=rng)

locdata.print_summary()
identifier: "1"
comment: ""
source: SIMULATION
state: RAW
element_count: 100
frame_count: 0
creation_time {
  2024-03-14T11:09:00.343556Z
}
fig, ax = plt.subplots(nrows=1, ncols=1)
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/540f8ad1c4b638a071da95b6308e88d929512e4d9be9ae42f00f3539cf015465.png

Minimal bounding box for spatial coordinates#

# H = BoundingBox(locdata.coordinates)

H = locdata.bounding_box

print('dimension: ', H.dimension)
print('hull: ', H.hull)
print('width: ', H.width)
print('vertices: ', H.vertices)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('region: ', H.region)
dimension:  2
hull:  [[ 2.490921    1.02997497]
 [92.36001123 89.71010693]]
width:  [89.86909023 88.68013196]
vertices:  [[ 2.490921   92.36001123]
 [ 1.02997497 89.71010693]]
region_measure:  7969.602780428899
subregion_measure:  357.0984443733635
region:  Rectangle((2.490921001041831, 1.0299749716244107), 89.86909022532446, 88.6801319613573, 0)
fig, ax = plt.subplots(nrows=1, ncols=1)
ax.add_patch(locdata.bounding_box.region.as_artist(alpha=0.2))
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/acb81711fef74cea0eca03dd1d4a3544544eaa7ccf7105fb2aaf2a33861b06bc.png

Oriented minimal bounding box for spatial coordinates#

# H = OrientedBoundingBox(locdata.coordinates)

H = locdata.oriented_bounding_box

print('dimension: ', H.dimension)
print('hull: ', H.hull)
print('vertices: ', H.vertices)
print('width: ', H.width)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('region: ', H.region)
dimension:  2
hull:  POLYGON ((-9.220392369565374 31.865082145844063, 59.69001056824682 -12.797641894321849, 97.75586149761332 45.934403275030405, 28.845458559801138 90.59712731519632, -9.220392369565374 31.865082145844063))
vertices:  [[ -9.22039237  31.86508215]
 [ 59.69001057 -12.79764189]
 [ 97.7558615   45.93440328]
 [ 28.84545856  90.59712732]
 [ -9.22039237  31.86508215]]
width:  [82.11822302 69.9890144 ]
region_measure:  5747.373493394239
subregion_measure:  304.21447483826086
region:  Rectangle((-9.220392369565374, 31.865082145844063), 82.11822301864336, 69.98901440048706, -32.948380191618504)
fig, ax = plt.subplots(nrows=1, ncols=1)
ax.add_patch(locdata.oriented_bounding_box.region.as_artist(alpha=0.2))
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/ddf43ef9f94ed0777c4961e0dff258366b035e8460a42cf8714920e8aaf7e90a.png

Convex hull#

Convex hull for spatial coordinates (scipy)#

# H = ConvexHull(locdata.coordinates, method='scipy')

H = locdata.convex_hull

print('dimension: ', H.dimension)
print('hull: ', H.hull)
# print('vertex_indices: ', H.vertex_indices)
# print('vertices: ', H.vertices)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('points on boundary: ', H.points_on_boundary)
print('points on boundary relative to all points: ', H.points_on_boundary_rel)
print('region: ', H.region)
dimension:  2
hull:  <scipy.spatial._qhull.ConvexHull object at 0x7fa3a7266ad0>
region_measure:  4908.170783871255
subregion_measure:  264.4870519254037
points on boundary:  13
points on boundary relative to all points:  0.13
region:  Polygon(<self.points>, <self.holes>)
fig, ax = plt.subplots(nrows=1, ncols=1)
ax.add_patch(locdata.convex_hull.region.as_artist(alpha=0.2))
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/fa640cc7b8bed1ffa242b2781c2e88437447bf5779b52a25f0b1ea098845721d.png

Convex hull for spatial coordinates (shapely)#

Some hulls can be computed from different algorithms. If implemented, use the methods parameter to specify the algorithm.

H = ConvexHull(locdata.coordinates, method='shapely')

print('dimension: ', H.dimension)
print('hull: ', H.hull)
# print('vertices: ', H.vertices)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('points on boundary: ', H.points_on_boundary)
print('points on boundary relative to all points: ', H.points_on_boundary_rel)
print('region: ', H.region)
dimension:  2
hull:  POLYGON ((54.029321929694525 1.0299749716244107, 48.634206414428576 1.294631346507537, 12.175420163612081 17.997868633149913, 9.18991822286495 21.36788078938049, 2.490921001041831 41.64287079543503, 26.54041545299338 87.040661544405, 30.214047987922243 89.71010693298172, 84.34954910628653 54.62340239857981, 91.9734281153137 41.17838012011845, 92.33940616216016 38.808549274650204, 92.36001122636628 38.48950874170735, 82.28290378326082 22.061077730066597, 79.83990217703906 19.69136737327613, 54.029321929694525 1.0299749716244107))
region_measure:  4908.170783871255
subregion_measure:  264.4870519254038
points on boundary:  13
points on boundary relative to all points:  0.13
region:  Polygon(<self.points>, <self.holes>)
fig, ax = plt.subplots(nrows=1, ncols=1)
ax.add_patch(H.region.as_artist(alpha=0.2))
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/7de3c3acf061fac9640370ed13a88b9923d27acdb63e1d7206bad2ae93f67cde.png

Alpha shape for spatial coordinates#

The alpha shape depends on a single parameter alpha (not to confuse with the alpha to specify opacity in figures). The alpha complex is an alpha-independent representation of all alpha shapes.

You can get all apha values for which the corresponding alpha shape changes.

lc.AlphaComplex(locdata.coordinates).alphas()
array([4.79010715e-02, 6.26886019e-02, 9.00848038e-02, 1.26327560e-01,
       1.27719280e-01, 1.35082505e-01, 1.48065929e-01, 1.59852612e-01,
       1.80345970e-01, 2.29967352e-01, 2.38528055e-01, 2.40927392e-01,
       2.41691338e-01, 2.66695006e-01, 2.77822554e-01, 2.94376165e-01,
       3.06743479e-01, 3.25282310e-01, 3.38425410e-01, 3.43041012e-01,
       3.43184730e-01, 3.52204265e-01, 3.57124009e-01, 3.58975685e-01,
       3.62059409e-01, 3.74195019e-01, 3.78291044e-01, 3.97084183e-01,
       4.00186670e-01, 4.02716245e-01, 4.02739384e-01, 4.02815627e-01,
       4.09114331e-01, 4.18957692e-01, 4.19645900e-01, 4.33534796e-01,
       4.47358936e-01, 4.47427686e-01, 4.50668384e-01, 4.56424309e-01,
       4.67180830e-01, 4.71727787e-01, 4.75216918e-01, 4.81397069e-01,
       4.81997429e-01, 4.82183979e-01, 4.97024836e-01, 4.99990289e-01,
       5.06241764e-01, 5.08056086e-01, 5.13489111e-01, 5.25320369e-01,
       5.31023418e-01, 5.34700206e-01, 5.39200680e-01, 5.49237405e-01,
       5.53496939e-01, 5.58987615e-01, 5.59448067e-01, 5.59500547e-01,
       5.61663190e-01, 5.67027377e-01, 5.67749948e-01, 5.71279300e-01,
       5.79365256e-01, 5.81500820e-01, 5.92288917e-01, 5.97516286e-01,
       6.00674458e-01, 6.01810488e-01, 6.03314803e-01, 6.06574504e-01,
       6.06739584e-01, 6.09413711e-01, 6.10483544e-01, 6.12523184e-01,
       6.18571992e-01, 6.19312766e-01, 6.20713067e-01, 6.24167482e-01,
       6.40082879e-01, 6.43777056e-01, 6.51568398e-01, 6.62458725e-01,
       6.64871359e-01, 6.82998920e-01, 6.89013581e-01, 6.89811876e-01,
       6.95662528e-01, 6.97159840e-01, 6.97171260e-01, 7.00419524e-01,
       7.00672239e-01, 7.09851240e-01, 7.11029883e-01, 7.12728093e-01,
       7.15296258e-01, 7.19308431e-01, 7.21811422e-01, 7.28223700e-01,
       7.34206960e-01, 7.37019513e-01, 7.38740770e-01, 7.39835123e-01,
       7.40429317e-01, 7.41294381e-01, 7.46229214e-01, 7.49077113e-01,
       7.50780227e-01, 7.51443768e-01, 7.58053002e-01, 7.59431180e-01,
       7.60230149e-01, 7.61763351e-01, 7.62155416e-01, 7.63885515e-01,
       7.69292534e-01, 7.70264128e-01, 7.71759040e-01, 7.73355937e-01,
       7.84442099e-01, 7.90069055e-01, 7.91274054e-01, 7.93463861e-01,
       7.94356991e-01, 7.99868788e-01, 8.03569058e-01, 8.11065191e-01,
       8.22856563e-01, 8.25466835e-01, 8.26052181e-01, 8.33933862e-01,
       8.39957725e-01, 8.44739640e-01, 8.45350979e-01, 8.46103046e-01,
       8.49224572e-01, 8.49880234e-01, 8.51344679e-01, 8.52808232e-01,
       8.53931434e-01, 8.56196465e-01, 8.61652127e-01, 8.69376152e-01,
       8.70334553e-01, 8.79922419e-01, 8.83510627e-01, 8.87756937e-01,
       8.87768808e-01, 8.89103801e-01, 8.90296830e-01, 9.03293099e-01,
       9.03545920e-01, 9.04654590e-01, 9.13895586e-01, 9.14988676e-01,
       9.19769930e-01, 9.21694582e-01, 9.25606663e-01, 9.42225183e-01,
       9.53726892e-01, 9.60716235e-01, 9.66079966e-01, 9.79994236e-01,
       9.82754216e-01, 9.85767096e-01, 9.88304664e-01, 9.93925311e-01,
       9.98617093e-01, 1.01493196e+00, 1.01705667e+00, 1.01784033e+00,
       1.02895805e+00, 1.03002195e+00, 1.03079742e+00, 1.03230173e+00,
       1.03437394e+00, 1.03953428e+00, 1.04708194e+00, 1.04779857e+00,
       1.05264932e+00, 1.06179970e+00, 1.06613206e+00, 1.06634542e+00,
       1.08018457e+00, 1.08501873e+00, 1.09518923e+00, 1.09869778e+00,
       1.10539327e+00, 1.11120765e+00, 1.11301014e+00, 1.11444086e+00,
       1.11952155e+00, 1.13356306e+00, 1.13477392e+00, 1.13733855e+00,
       1.15128479e+00, 1.15750823e+00, 1.16736695e+00, 1.16926401e+00,
       1.17387209e+00, 1.18535636e+00, 1.18551348e+00, 1.19292617e+00,
       1.19896186e+00, 1.20048927e+00, 1.20720985e+00, 1.23595162e+00,
       1.23873969e+00, 1.25573200e+00, 1.25617021e+00, 1.26070725e+00,
       1.26125038e+00, 1.26240010e+00, 1.26532192e+00, 1.27488250e+00,
       1.27724424e+00, 1.28234004e+00, 1.28497224e+00, 1.29840781e+00,
       1.30029954e+00, 1.31068196e+00, 1.31351678e+00, 1.31691837e+00,
       1.31734890e+00, 1.33458446e+00, 1.33515579e+00, 1.34370910e+00,
       1.34568550e+00, 1.34663685e+00, 1.34907880e+00, 1.35972579e+00,
       1.36367900e+00, 1.36709957e+00, 1.36739479e+00, 1.41309146e+00,
       1.42226765e+00, 1.42571135e+00, 1.43547786e+00, 1.43628331e+00,
       1.45069543e+00, 1.46565390e+00, 1.48152517e+00, 1.48366972e+00,
       1.48804400e+00, 1.49016566e+00, 1.52334060e+00, 1.52574832e+00,
       1.52870001e+00, 1.53542071e+00, 1.53864429e+00, 1.54408771e+00,
       1.54595694e+00, 1.55976987e+00, 1.57562096e+00, 1.58411018e+00,
       1.61295349e+00, 1.61741832e+00, 1.62776308e+00, 1.63307779e+00,
       1.63940332e+00, 1.64733370e+00, 1.65626521e+00, 1.65788434e+00,
       1.66678718e+00, 1.69711226e+00, 1.70174793e+00, 1.71050339e+00,
       1.71714404e+00, 1.72508327e+00, 1.73141334e+00, 1.73774244e+00,
       1.74668941e+00, 1.74747826e+00, 1.75133241e+00, 1.75463569e+00,
       1.77157747e+00, 1.77362769e+00, 1.77744793e+00, 1.78223117e+00,
       1.78501180e+00, 1.79207963e+00, 1.79918946e+00, 1.80015981e+00,
       1.82414077e+00, 1.82536675e+00, 1.87379584e+00, 1.89357272e+00,
       1.91381607e+00, 1.92656279e+00, 1.94884908e+00, 2.00577717e+00,
       2.01728998e+00, 2.03034431e+00, 2.04408104e+00, 2.05038818e+00,
       2.05349095e+00, 2.07285481e+00, 2.16816869e+00, 2.20910083e+00,
       2.22509947e+00, 2.24795084e+00, 2.25112215e+00, 2.27054590e+00,
       2.27811322e+00, 2.27983143e+00, 2.31343855e+00, 2.32264410e+00,
       2.32880977e+00, 2.34437210e+00, 2.37718224e+00, 2.37723128e+00,
       2.38295290e+00, 2.39569231e+00, 2.41090942e+00, 2.43550447e+00,
       2.45645949e+00, 2.45891276e+00, 2.52246605e+00, 2.54215315e+00,
       2.62136822e+00, 2.65112497e+00, 2.65972828e+00, 2.70080147e+00,
       2.79515289e+00, 2.84755996e+00, 2.85697323e+00, 2.90416046e+00,
       3.01656649e+00, 3.07917748e+00, 3.13521975e+00, 3.17783655e+00,
       3.26467278e+00, 3.38255925e+00, 3.56990862e+00, 3.57574974e+00,
       3.59260960e+00, 3.60194779e+00, 3.63036096e+00, 3.69906825e+00,
       3.95779301e+00, 4.26390245e+00, 4.29842013e+00, 4.90182079e+00,
       4.97166259e+00, 6.07922626e+00, 6.24118004e+00, 6.24890464e+00,
       6.35586273e+00, 6.39866293e+00, 6.48277005e+00, 6.65001925e+00,
       6.94378885e+00, 7.14344811e+00, 7.21201452e+00, 7.24911348e+00,
       7.26452608e+00, 7.32337306e+00, 7.41191471e+00, 7.42595448e+00,
       7.43392888e+00, 7.43433203e+00, 7.72806825e+00, 7.74336647e+00,
       7.76087118e+00, 7.78944873e+00, 7.80165047e+00, 7.82652969e+00,
       7.85021562e+00, 7.87716234e+00, 7.88724780e+00, 7.96646223e+00,
       8.04566727e+00, 8.08224562e+00, 8.09483397e+00, 8.26562220e+00,
       8.31591730e+00, 8.51342985e+00, 8.71703225e+00, 8.74628027e+00,
       8.79373820e+00, 8.94187403e+00, 8.95071004e+00, 9.00003635e+00,
       9.01595702e+00, 9.63640804e+00, 9.86227445e+00, 1.01897890e+01,
       1.02221135e+01, 1.02751450e+01, 1.03599403e+01, 1.03913311e+01,
       1.04465878e+01, 1.04471172e+01, 1.04597259e+01, 1.05636147e+01,
       1.05639307e+01, 1.05738881e+01, 1.06432177e+01, 1.06765138e+01,
       1.08061930e+01, 1.08267337e+01, 1.10126155e+01, 1.11019300e+01,
       1.17944937e+01, 1.17991373e+01, 1.19695055e+01, 1.20037920e+01,
       1.21184799e+01, 1.22848303e+01, 1.30919383e+01, 1.50017504e+01,
       1.51307502e+01, 1.53817915e+01, 1.58322884e+01, 1.59250873e+01,
       1.59542235e+01, 1.59653821e+01, 1.66977766e+01, 1.75114153e+01,
       1.76752204e+01, 1.77796252e+01, 1.77821903e+01, 1.78396689e+01,
       1.78495038e+01, 1.78527366e+01, 1.80088206e+01, 1.87142131e+01,
       1.89454045e+01, 1.89693286e+01, 1.89963288e+01, 1.90443274e+01,
       1.91047288e+01, 1.91360626e+01, 1.91361642e+01, 1.91392739e+01,
       1.91597195e+01, 1.91653265e+01, 1.91703660e+01, 1.91811000e+01,
       1.92761620e+01, 1.94600972e+01, 1.96390949e+01, 2.00514415e+01,
       2.02227234e+01, 2.15705094e+01, 2.39869621e+01, 2.41473984e+01,
       2.41540455e+01, 2.44485075e+01, 2.46186883e+01, 2.56872419e+01,
       2.63949037e+01, 2.70955193e+01, 2.78666861e+01, 2.82256845e+01,
       2.95858969e+01, 2.98130814e+01, 3.06827051e+01, 3.22557333e+01,
       3.70800737e+01, 5.09825269e+01, 5.34146215e+01, 7.99051776e+01,
       9.91221385e+01, 1.42276409e+02, 4.34636400e+02, 4.71113175e+02,
       1.32363587e+03,            inf])

You can determine an optimal alpha, i.e. the smallest alpha for which all points are still part of the alpha shape.

opt_alpha = lc.AlphaComplex(locdata.coordinates).optimal_alpha()
opt_alpha
32.25573327495765
# H = lc.AlphaShape(opt_alpha, locdata.coordinates)

locdata.update_alpha_shape(alpha=opt_alpha)
H = locdata.alpha_shape

print('dimension: ', H.dimension)
# print('vertex_indices: ', H.vertex_indices)
# print('vertices: ', H.vertices)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('points in alpha shape: ', H.n_points_alpha_shape)
print('points in alpha shape relative to all points: ', H.n_points_alpha_shape_rel)
print('points on boundary: ', H.n_points_on_boundary)
print('points on boundary relative to all points: ', H.n_points_on_boundary_rel)
print('region: ', H.region)
dimension:  2
region_measure:  4908.1707838712555
subregion_measure:  264.4870519254038
points in alpha shape:  100
points in alpha shape relative to all points:  1.0
points on boundary:  22
points on boundary relative to all points:  0.22
region:  Polygon(<self.points>, <self.holes>)

The alpha shape is made of different vertex types that can be differentiated as exterior, interior, regular or singular.

ac_simplices_all = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='all')
ac_simplices_exterior = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='exterior')
ac_simplices_interior = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='interior')
ac_simplices_regular = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='regular')
ac_simplices_singular = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='singular')
fig, ax = plt.subplots(nrows=1, ncols=1)

for simp in ac_simplices_all:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '-b')
for simp in ac_simplices_interior:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--g')
for simp in ac_simplices_regular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--r')
for simp in ac_simplices_singular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--y')

locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/17179b3be447f888be51c71f7fad92cbd890638d02a047bb5fd50fd4f6f13daa.png

Often the regular representation is good enough.

fig, ax = plt.subplots(nrows=1, ncols=1)
for simp in ac_simplices_regular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '-r')
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/2b1d4c1ffd35678c2d99570620808561803623e610fdb6e46cc49dfbe8e8ede2.png

You can get the connected components as list of Region.

H.connected_components
[Polygon([[26.54041545299338, 87.040661544405], [30.214047987922243, 89.71010693298172], [84.34954910628653, 54.62340239857981], [91.9734281153137, 41.17838012011845], [92.33940616216016, 38.808549274650204], [92.36001122636628, 38.48950874170735], [82.28290378326082, 22.061077730066597], [79.83990217703906, 19.69136737327613], [54.029321929694525, 1.0299749716244107], [48.634206414428576, 1.294631346507537], [12.175420163612081, 17.997868633149913], [9.18991822286495, 21.36788078938049], [2.490921001041831, 41.64287079543503], [26.54041545299338, 87.040661544405]], [])]
connected_component_0 = H.connected_components[0]

print('dimension: ', connected_component_0.dimension)
print('region_measure: ', connected_component_0.region_measure)
print('subregion_measure: ', connected_component_0.subregion_measure)
dimension:  2
region_measure:  4908.1707838712555
subregion_measure:  264.4870519254038

The alpha shape for a smaller alpha can have multiple connected components.

H = lc.AlphaShape(5, locdata.coordinates)

print('dimension: ', H.dimension)
# print('vertex_indices: ', H.vertex_indices)
# print('vertices: ', H.vertices)
print('region_measure: ', H.region_measure)
print('subregion_measure: ', H.subregion_measure)
print('points in alpha shape: ', H.n_points_alpha_shape)
print('points in alpha shape relative to all points: ', H.n_points_alpha_shape_rel)
print('points on boundary: ', H.n_points_on_boundary)
print('points on boundary relative to all points: ', H.n_points_on_boundary_rel)
dimension:  2
region_measure:  178.41254317639843
subregion_measure:  171.67742405936463
points in alpha shape:  100
points in alpha shape relative to all points:  1.0
points on boundary:  57
points on boundary relative to all points:  0.57
ac_simplices_all = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='all')
ac_simplices_exterior = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='exterior')
ac_simplices_interior = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='interior')
ac_simplices_regular = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='regular')
ac_simplices_singular = H.alpha_complex.get_alpha_complex_lines(H.alpha, type='singular')
fig, ax = plt.subplots(nrows=1, ncols=1)

for simp in ac_simplices_all:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '-b')
for simp in ac_simplices_interior:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--g')
for simp in ac_simplices_regular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--r')
for simp in ac_simplices_singular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '--y')

locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/4624806a361508acb90a89ab3fc74488e598854c02ff733b18efaae114fa4a0f.png

The regular representation:

fig, ax = plt.subplots(nrows=1, ncols=1)
for simp in ac_simplices_regular:
    ax.plot(locdata.coordinates[simp, 0], locdata.coordinates[simp, 1], '-r')
locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')
plt.show()
../../_images/261b06f94c991c0dc78e19cdaea62d56914dd18b5853ce31b7d4ed875814efbc.png

The connected components:

H.connected_components
[Polygon([[4.574030584926964, 35.4547363609949], [2.490921001041831, 41.64287079543503], [4.957382196904078, 39.08282122381802], [8.355461487809666, 36.04765129727869], [8.66131719294932, 35.8564682341916], [4.574030584926964, 35.4547363609949]], []),
 Polygon([[25.770117329307787, 41.124276031608815], [23.31756949147803, 42.6744624631213], [20.173587957294433, 44.31714346765541], [22.361223833116604, 46.453014294097834], [28.048700032796415, 46.15804762285728], [31.339293507790977, 45.9942555369238], [25.770117329307787, 41.124276031608815]], []),
 Polygon([[9.18991822286495, 21.36788078938049], [12.636282213847565, 21.529820077010385], [14.734872660721315, 19.880462363217678], [14.769094009431546, 19.124654613922488], [14.266019685598483, 18.241818179484355], [13.747576761626673, 17.702091783845788], [12.175420163612081, 17.997868633149913], [9.18991822286495, 21.36788078938049]], []),
 Polygon([[26.54041545299338, 87.040661544405], [30.214047987922243, 89.71010693298172], [31.521384860659595, 86.75121552412102], [32.14133335513356, 83.41408741528058], [29.20688463095611, 81.48951050894098], [26.54041545299338, 87.040661544405]], []),
 Polygon([[79.18789302054475, 52.543982100600005], [79.11703202181116, 56.39645603252982], [81.32782142473194, 55.75284367902573], [84.34954910628653, 54.62340239857981], [80.25475558909794, 52.61761293856212], [79.18789302054475, 52.543982100600005]], []),
 Polygon([[87.6064843703255, 42.247461144808746], [91.9734281153137, 41.17838012011845], [92.33940616216016, 38.808549274650204], [92.36001122636628, 38.48950874170735], [91.40098079916173, 36.989250622930314], [90.7011218417029, 35.889994988035625], [86.13341308357771, 38.463382259593324], [87.6064843703255, 42.247461144808746]], []),
 Polygon([[54.029321929694525, 1.0299749716244107], [48.634206414428576, 1.294631346507537], [49.59358344008751, 3.4015003371361145], [53.482683026695234, 6.614947738231005], [54.37183424361821, 3.788452129115082], [55.03000267597442, 2.3642990669580453], [54.029321929694525, 1.0299749716244107]], []),
 Polygon([[53.02310815665912, 20.494919113980316], [52.4417533406316, 23.609344720491215], [56.99055629523848, 24.610250050117035], [57.896406888972834, 22.172515398810596], [57.98560316805971, 21.06912087658576], [58.31284235106916, 17.772793788937257], [55.04194051962414, 18.999536120747145], [53.02310815665912, 20.494919113980316]], []),
 Polygon([[78.79284317381992, 22.962147412197464], [77.83372328947765, 26.395146222813697], [81.19928424977152, 23.660768547251035], [82.28290378326082, 22.061077730066597], [79.83990217703906, 19.69136737327613], [78.79284317381992, 22.962147412197464]], [])]
connected_component_0 = H.connected_components[0]

print('dimension: ', connected_component_0.dimension)
print('region_measure: ', connected_component_0.region_measure)
print('subregion_measure: ', connected_component_0.subregion_measure)
dimension:  2
region_measure:  12.16313947011497
subregion_measure:  19.10814169604162