<jupyter_start><jupyter_text>Fractopo – Fracture Network Analysis<jupyter_code>import warnings

warnings.filterwarnings("ignore")
# Cell contents only required for development env runs
from importlib.util import find_spec

if find_spec("fractopo") is None:
    import sys

    sys.path.append("..")
from fractopo.analysis.network import Network
import fractopo.contour_grid as contour_grid
import matplotlib.pyplot as plt
import geopandas as gpd

plt.close()<jupyter_output><empty_output><jupyter_text>Data Trace and target area data required. The paths can be urls to GeoJSON or local file paths to spatial filetypes (e.g. shapefile, geopackage). The name is used in plot labels and titles.<jupyter_code>trace_data = ""
area_data = ""
name = ""
# Parameters
trace_data = "/mnt/d/Data/trace_repo/ahvenanmaa/traces/20m/Getaberget_20m_4_traces.gpkg"
area_data = "/mnt/d/Data/trace_repo/ahvenanmaa/areas/20m/Getaberget_20m_4_1_area.gpkg"
name = "Getaberget_20m_4_1_area"<jupyter_output><empty_output><jupyter_text>The defaults in the next cell are only applied if no parameters are given to the above cell.<jupyter_code>if len(trace_data) == 0:
    # Set defaults
    # Trace and target area data available on GitHub
    trace_data = "https://raw.githubusercontent.com/nialov/fractopo/master/tests/sample_data/KB11/KB11_traces.geojson"
    area_data = "https://raw.githubusercontent.com/nialov/fractopo/master/tests/sample_data/KB11/KB11_area.geojson"
    # Name the dataset
    name = "KB11"
# Use geopandas to load data from urls
traces = gpd.read_file(trace_data)
area = gpd.read_file(area_data)
area.total_bounds
def focus_plot_to_bounds(ax, total_bounds):
    xmin, ymin, xmax, ymax = total_bounds
    extend_x = (xmax - xmin) * 0.05
    extend_y = (ymax - ymin) * 0.05
    ax.set_xlim(xmin - extend_x, xmax + extend_x)
    ax.set_ylim(ymin - extend_y, ymax + extend_y)
    return ax<jupyter_output><empty_output><jupyter_text>Visualizing trace map data<jupyter_code>fix, ax = plt.subplots(figsize=(9, 9))
traces.plot(ax=ax, color="blue")
area.boundary.plot(ax=ax, color="red")
ax = focus_plot_to_bounds(ax, area.total_bounds)<jupyter_output><empty_output><jupyter_text>Create Network<jupyter_code># Create Network and automatically determine branches and nodes
network = Network(
    traces, area, name=name, determine_branches_nodes=True, snap_threshold=0.001
)<jupyter_output><empty_output><jupyter_text>Visualizing branches and nodes<jupyter_code>from fractopo.general import CC_branch, CI_branch, II_branch, X_node, Y_node, I_node


# Function to determine color for each branch and node type
def assign_colors(feature_type: str):
    if feature_type in (CC_branch, X_node):
        return "green"
    if feature_type in (CI_branch, Y_node):
        return "blue"
    if feature_type in (II_branch, I_node):
        return "black"
    return "red"<jupyter_output><empty_output><jupyter_text>| Branch or Node Type | Color ||---------------------|-------|| C - C, X            | Green || C - I, Y            | Blue  || I - I, I            | Black || Other               | Red   |  Branches<jupyter_code>fix, ax = plt.subplots(figsize=(9, 9))
network.branch_gdf.plot(
    colors=[assign_colors(bt) for bt in network.branch_types], ax=ax
)
area.boundary.plot(ax=ax, color="red")<jupyter_output><empty_output><jupyter_text>Nodes<jupyter_code>fix, ax = plt.subplots(figsize=(9, 9))
# Traces
network.trace_gdf.plot(ax=ax, linewidth=0.5)
# Nodes
network.node_gdf.plot(
    c=[assign_colors(bt) for bt in network.node_types], ax=ax, markersize=10
)
area.boundary.plot(ax=ax, color="red")
ax = focus_plot_to_bounds(ax, area.total_bounds)<jupyter_output><empty_output><jupyter_text>Rose plots<jupyter_code># Plot azimuth rose plot of fracture traces
azimuth_bin_dict, fig, ax = network.plot_trace_azimuth()<jupyter_output><empty_output><jupyter_text>Length distributions  Trace length distribution<jupyter_code># Fit for traces
fit_traces = network.trace_lengths_powerlaw_fit()
# Plot length distribution fits (powerlaw, exponential and lognormal) of fracture traces
fit, fig, ax = network.plot_trace_lengths()
# Fit properties
print(f"Automatically determined powerlaw cut-off: {fit_traces.xmin}")
print(f"Powerlaw exponent: {fit_traces.alpha - 1}")
print(
    f"Proportion of data cut off by cut off: {network.trace_lengths_cut_off_proportion()}"
)
print(
    f"Compare powerlaw fit to lognormal: R, p = {fit_traces.distribution_compare('power_law', 'lognormal')}"
)<jupyter_output>Automatically determined powerlaw cut-off: 1.7569282810294788
Powerlaw exponent: 1.0775984618831593
Proportion of data cut off by cut off: 0.5314009661835749
Compare powerlaw fit to lognormal: R, p = (-0.13606703531104292, 0.6999705241551295)<jupyter_text>Branch length distribution<jupyter_code># Fit for branches
fit_branches = network.branch_lengths_powerlaw_fit()
# Plot length distribution fits (powerlaw, exponential and lognormal) of fracture branches
fit, fig, ax = network.plot_branch_lengths()
# Fit properties
print(f"Automatically determined powerlaw cut-off: {fit_branches.xmin}")
print(f"Powerlaw exponent: {fit_branches.alpha - 1}")
print(
    f"Proportion of data cut off by cut off: {network.branch_lengths_cut_off_proportion()}"
)
print(
    f"Compare powerlaw fit to lognormal: R, p = {fit_branches.distribution_compare('power_law', 'lognormal')}"
)<jupyter_output>Automatically determined powerlaw cut-off: 1.5429421791883207
Powerlaw exponent: 1.4017922323193712
Proportion of data cut off by cut off: 0.6863753213367609
Compare powerlaw fit to lognormal: R, p = (-0.21788742992362953, 0.6838435625455233)<jupyter_text>Crosscutting and abutting relationships<jupyter_code># Sets are defaults
print(f"Azimuth set names: {network.azimuth_set_names}")
print(f"Azimuth set ranges: {network.azimuth_set_ranges}")
# Plot crosscutting and abutting relationships between azimuth sets
figs, fig_axes = network.plot_azimuth_crosscut_abutting_relationships()<jupyter_output><empty_output><jupyter_text>Node and branch proportions<jupyter_code>network.node_counts
# Plot ternary XYI-node proportion plot
fig, ax, tax = network.plot_xyi()
network.branch_counts
# Plot ternary branch (C-C, C-I, I-I) proportion plot
fig, ax, tax = network.plot_branch()<jupyter_output><empty_output><jupyter_text>General topological and geometric parameters<jupyter_code>network.parameters<jupyter_output><empty_output><jupyter_text>Contour grids for target area<jupyter_code>sampled_grid = contour_grid.run_grid_sampling(
    traces=network.trace_gdf,
    branches=network.branch_gdf,
    nodes=network.node_gdf,
    cell_width=1.0,
    snap_threshold=0.01,
)
sampled_grid.columns
# From https://geopandas.org/mapping.html
from mpl_toolkits.axes_grid1 import make_axes_locatable


def plot_contour(column: str):
    fig, ax = plt.subplots(1, 1, figsize=(12, 12))
    divider = make_axes_locatable(ax)
    cax = divider.append_axes("right", size="5%", pad=0.1)
    sampled_grid.plot(
        column=column, legend=True, cax=cax, ax=ax, legend_kwds={"label": column}
    )
plot_contour("Fracture Intensity P21")
plot_contour("Connections per Branch")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10826689047419219, 'fraction_numerical': 0.0331514897188418, 'mean_word_length': 5.732580037664784, 'pattern_counts': {'":': 1, '<': 59, '<?xml version=': 0, '>': 59, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '105944', 'license': 'MIT', 'n_tokens_mistral': 2692, 'n_tokens_neox': 2492, 'n_words': 560, 'path': 'scripts_and_notebooks/notebooks/analyzed/fractopo_network_Getaberget_20m_4_1_area.ipynb', 'repo_name': 'nialov/fractopo-subsampling', 'size': '7149'}