well-log-toolkit 0.1.139__tar.gz → 0.1.140__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/PKG-INFO +1 -1
  2. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/pyproject.toml +1 -1
  3. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/visualization.py +66 -9
  4. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit.egg-info/PKG-INFO +1 -1
  5. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/README.md +0 -0
  6. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/setup.cfg +0 -0
  7. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/__init__.py +0 -0
  8. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/exceptions.py +0 -0
  9. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/las_file.py +0 -0
  10. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/manager.py +0 -0
  11. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/operations.py +0 -0
  12. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/property.py +0 -0
  13. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/regression.py +0 -0
  14. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/statistics.py +0 -0
  15. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/utils.py +0 -0
  16. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit/well.py +0 -0
  17. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit.egg-info/SOURCES.txt +0 -0
  18. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit.egg-info/dependency_links.txt +0 -0
  19. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit.egg-info/requires.txt +0 -0
  20. {well_log_toolkit-0.1.139 → well_log_toolkit-0.1.140}/well_log_toolkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: well-log-toolkit
3
- Version: 0.1.139
3
+ Version: 0.1.140
4
4
  Summary: Fast LAS file processing with lazy loading and filtering for well log analysis
5
5
  Author-email: Kristian dF Kollsgård <kkollsg@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "well-log-toolkit"
7
- version = "0.1.139"
7
+ version = "0.1.140"
8
8
  description = "Fast LAS file processing with lazy loading and filtering for well log analysis"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -14,7 +14,7 @@ import pandas as pd
14
14
  import matplotlib.pyplot as plt
15
15
  import matplotlib.cm as cm
16
16
  from matplotlib.collections import PolyCollection
17
- from matplotlib.colors import Normalize
17
+ from matplotlib.colors import Normalize, LogNorm
18
18
  from matplotlib.patches import Rectangle, Patch
19
19
 
20
20
  if TYPE_CHECKING:
@@ -2137,6 +2137,20 @@ class WellView:
2137
2137
  crossover_mask = left_values > right_values
2138
2138
  left_values = np.where(crossover_mask, right_values, left_values)
2139
2139
 
2140
+ # Create valid mask - skip points where boundary values are NaN
2141
+ boundary_valid_mask = ~(np.isnan(left_values) | np.isnan(right_values))
2142
+
2143
+ # Filter arrays to only valid points
2144
+ if not np.all(boundary_valid_mask):
2145
+ left_values = left_values[boundary_valid_mask]
2146
+ right_values = right_values[boundary_valid_mask]
2147
+ depth_for_fill = depth_for_fill[boundary_valid_mask]
2148
+ n_points = len(depth_for_fill)
2149
+
2150
+ if n_points < 2:
2151
+ # Not enough valid points to draw fill
2152
+ return
2153
+
2140
2154
  # Apply fill
2141
2155
  fill_color = fill.get("color", "lightblue")
2142
2156
  fill_alpha = fill.get("alpha", 0.3)
@@ -2171,6 +2185,10 @@ class WellView:
2171
2185
  warnings.warn("Cannot determine colormap values (no curve specified for left or right)")
2172
2186
  return
2173
2187
 
2188
+ # Apply same boundary mask to colormap values
2189
+ if not np.all(boundary_valid_mask):
2190
+ colormap_values = colormap_values[boundary_valid_mask]
2191
+
2174
2192
  # Get color range for normalization
2175
2193
  # Check if we have valid values
2176
2194
  valid_mask = ~np.isnan(colormap_values)
@@ -2179,7 +2197,17 @@ class WellView:
2179
2197
  return
2180
2198
 
2181
2199
  color_range = fill.get("color_range", [np.nanmin(colormap_values), np.nanmax(colormap_values)])
2182
- norm = Normalize(vmin=color_range[0], vmax=color_range[1])
2200
+ # Default color_log to track's log_scale setting
2201
+ color_log = fill.get("color_log", track_log_scale)
2202
+
2203
+ # Use LogNorm for log scale colormap, Normalize for linear
2204
+ if color_log:
2205
+ # Ensure positive values for log scale
2206
+ vmin = max(color_range[0], 1e-10)
2207
+ vmax = max(color_range[1], vmin * 10)
2208
+ norm = LogNorm(vmin=vmin, vmax=vmax)
2209
+ else:
2210
+ norm = Normalize(vmin=color_range[0], vmax=color_range[1])
2183
2211
  cmap = plt.get_cmap(cmap_name)
2184
2212
 
2185
2213
  # Create horizontal bands - each depth interval gets a color based on the curve value
@@ -2274,7 +2302,8 @@ class WellView:
2274
2302
  ax: plt.Axes,
2275
2303
  fill: dict,
2276
2304
  plotted_curves: dict,
2277
- depth: np.ndarray
2305
+ depth: np.ndarray,
2306
+ track_log_scale: bool = False
2278
2307
  ) -> None:
2279
2308
  """
2280
2309
  Add fill between curves or values.
@@ -2349,6 +2378,20 @@ class WellView:
2349
2378
  crossover_mask = left_values > right_values
2350
2379
  left_values = np.where(crossover_mask, right_values, left_values)
2351
2380
 
2381
+ # Create valid mask - skip points where boundary values are NaN
2382
+ boundary_valid_mask = ~(np.isnan(left_values) | np.isnan(right_values))
2383
+
2384
+ # Filter arrays to only valid points
2385
+ depth_for_fill = depth # Use local variable for consistency
2386
+ if not np.all(boundary_valid_mask):
2387
+ left_values = left_values[boundary_valid_mask]
2388
+ right_values = right_values[boundary_valid_mask]
2389
+ depth_for_fill = depth[boundary_valid_mask]
2390
+
2391
+ if len(depth_for_fill) < 2:
2392
+ # Not enough valid points to draw fill
2393
+ return
2394
+
2352
2395
  # Apply fill
2353
2396
  fill_color = fill.get("color", "lightblue")
2354
2397
  fill_alpha = fill.get("alpha", 0.3)
@@ -2383,6 +2426,10 @@ class WellView:
2383
2426
  warnings.warn("Cannot determine colormap values (no curve specified for left or right)")
2384
2427
  return
2385
2428
 
2429
+ # Apply same boundary mask to colormap values
2430
+ if not np.all(boundary_valid_mask):
2431
+ colormap_values = colormap_values[boundary_valid_mask]
2432
+
2386
2433
  # Get color range for normalization
2387
2434
  # Check if we have valid values
2388
2435
  valid_mask = ~np.isnan(colormap_values)
@@ -2391,12 +2438,22 @@ class WellView:
2391
2438
  return
2392
2439
 
2393
2440
  color_range = fill.get("color_range", [np.nanmin(colormap_values), np.nanmax(colormap_values)])
2394
- norm = Normalize(vmin=color_range[0], vmax=color_range[1])
2441
+ # Default color_log to track's log_scale setting
2442
+ color_log = fill.get("color_log", track_log_scale)
2443
+
2444
+ # Use LogNorm for log scale colormap, Normalize for linear
2445
+ if color_log:
2446
+ # Ensure positive values for log scale
2447
+ vmin = max(color_range[0], 1e-10)
2448
+ vmax = max(color_range[1], vmin * 10)
2449
+ norm = LogNorm(vmin=vmin, vmax=vmax)
2450
+ else:
2451
+ norm = Normalize(vmin=color_range[0], vmax=color_range[1])
2395
2452
  cmap = plt.get_cmap(cmap_name)
2396
2453
 
2397
2454
  # Create horizontal bands - each depth interval gets a color based on the curve value
2398
2455
  # Use PolyCollection for performance (1000x faster than loop with fill_betweenx)
2399
- n_intervals = len(depth) - 1
2456
+ n_intervals = len(depth_for_fill) - 1
2400
2457
 
2401
2458
  # Compute color values for each interval (average of adjacent points)
2402
2459
  color_values = (colormap_values[:-1] + colormap_values[1:]) / 2
@@ -2407,10 +2464,10 @@ class WellView:
2407
2464
  verts = []
2408
2465
  for i in range(n_intervals):
2409
2466
  verts.append([
2410
- (left_values[i], depth[i]),
2411
- (right_values[i], depth[i]),
2412
- (right_values[i+1], depth[i+1]),
2413
- (left_values[i+1], depth[i+1])
2467
+ (left_values[i], depth_for_fill[i]),
2468
+ (right_values[i], depth_for_fill[i]),
2469
+ (right_values[i+1], depth_for_fill[i+1]),
2470
+ (left_values[i+1], depth_for_fill[i+1])
2414
2471
  ])
2415
2472
 
2416
2473
  # Create PolyCollection with all polygons at once
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: well-log-toolkit
3
- Version: 0.1.139
3
+ Version: 0.1.140
4
4
  Summary: Fast LAS file processing with lazy loading and filtering for well log analysis
5
5
  Author-email: Kristian dF Kollsgård <kkollsg@gmail.com>
6
6
  License: MIT