nettracer3d 0.7.8__py3-none-any.whl → 0.8.0__py3-none-any.whl

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.
nettracer3d/proximity.py CHANGED
@@ -361,7 +361,7 @@ def convert_centroids_to_array(centroids_list, xy_scale = 1, z_scale = 1):
361
361
  """
362
362
  # Determine how many centroids we have
363
363
  n_points = len(centroids_list)
364
-
364
+
365
365
  # Get dimensionality from the first centroid
366
366
  dim = len(list(centroids_list)[0])
367
367
 
@@ -404,7 +404,12 @@ def generate_r_values(points_array, step_size, bounds = None, dim = 2, max_propo
404
404
 
405
405
 
406
406
  # Calculate the longest dimension
407
- dimensions = max_coords - min_coords
407
+ try:
408
+ dimensions = max_coords - min_coords
409
+ except: # Presume dimension mismatch
410
+ min_coords = np.array([0,0,0])
411
+ dimensions = max_coords - min_coords
412
+
408
413
  max_dimension = np.max(dimensions)
409
414
 
410
415
  # Calculate maximum r value (typically half the shortest side for 2D,
@@ -459,7 +464,10 @@ def optimized_ripleys_k(reference_points, subset_points, r_values, bounds=None,
459
464
  # Calculate volume of study area
460
465
  min_bounds, max_bounds = bounds
461
466
  sides = max_bounds - min_bounds
462
- volume = np.prod(sides)
467
+ if dim == 2:
468
+ volume = sides[0] * sides[1]
469
+ else:
470
+ volume = np.prod(sides)
463
471
 
464
472
  # Point intensity (points per unit volume)
465
473
  intensity = n_ref / volume
@@ -618,7 +626,7 @@ def compute_ripleys_h(k_values, r_values, dimension=2):
618
626
  else:
619
627
  raise ValueError("Dimension must be 2 or 3")
620
628
 
621
- def plot_ripley_functions(r_values, k_values, h_values, dimension=2, figsize=(12, 5)):
629
+ def plot_ripley_functions(r_values, k_values, h_values, dimension=2, rootiden = None, compiden = None, figsize=(12, 5)):
622
630
  """
623
631
  Plot Ripley's K and H functions with theoretical Poisson distribution references
624
632
  adjusted for edge effects.
@@ -651,7 +659,10 @@ def plot_ripley_functions(r_values, k_values, h_values, dimension=2, figsize=(12
651
659
  ax1.plot(r_values, theo_k, 'r--', label='Theoretical K(r) for CSR')
652
660
  ax1.set_xlabel('Distance (r)')
653
661
  ax1.set_ylabel('L(r)')
654
- ax1.set_title("Ripley's K Function")
662
+ if rootiden is None or compiden is None:
663
+ ax1.set_title("Ripley's K Function")
664
+ else:
665
+ ax1.set_title(f"Ripley's K Function for {compiden} Clustering Around {rootiden}")
655
666
  ax1.legend()
656
667
  ax1.grid(True, alpha=0.3)
657
668
 
@@ -660,7 +671,10 @@ def plot_ripley_functions(r_values, k_values, h_values, dimension=2, figsize=(12
660
671
  ax2.plot(r_values, theo_h, 'r--', label='Theoretical H(r) for CSR')
661
672
  ax2.set_xlabel('Distance (r)')
662
673
  ax2.set_ylabel('L(r) Normalized')
663
- ax2.set_title("Ripley's H Function")
674
+ if rootiden is None or compiden is None:
675
+ ax2.set_title("Ripley's H Function")
676
+ else:
677
+ ax2.set_title(f"Ripley's H Function for {compiden} Clustering Around {rootiden}")
664
678
  ax2.axhline(y=0, color='k', linestyle='-', alpha=0.3)
665
679
  ax2.legend()
666
680
  ax2.grid(True, alpha=0.3)
nettracer3d/segmenter.py CHANGED
@@ -1412,7 +1412,7 @@ class InteractiveSegmenter:
1412
1412
  use_two=self.use_two,
1413
1413
  mem_lock=self.mem_lock)
1414
1414
 
1415
- print(f"Model data saved to {file_name}")
1415
+ print(f"Model data saved to {file_name}. Please retrain current model prior to segmentation.")
1416
1416
 
1417
1417
 
1418
1418
  def load_model(self, file_name):
@@ -1221,7 +1221,7 @@ class InteractiveSegmenter:
1221
1221
  use_two=self.use_two,
1222
1222
  mem_lock=self.mem_lock)
1223
1223
 
1224
- print(f"Model data saved to {file_name}")
1224
+ print(f"Model data saved to {file_name}. Please retrain current model prior to segmentation.")
1225
1225
 
1226
1226
 
1227
1227
  def load_model(self, file_name):
@@ -174,32 +174,50 @@ def show_identity_network(excel_file_path, node_identities, geometric=False, geo
174
174
  G = nx.Graph()
175
175
  G.add_edges_from(edges)
176
176
 
177
- # Create a more sophisticated color palette using a combination of colormap sequences
177
+ # ENHANCED COLOR LOGIC - Generate bright, contrasting colors
178
178
  unique_categories = list(set(identity_dict.values()))
179
179
  num_categories = len(unique_categories)
180
180
 
181
- # Create a color palette that combines multiple colormaps for more distinct colors
182
- if num_categories <= 10:
183
- colors = plt.cm.tab10(np.linspace(0, 1, num_categories))
184
- elif num_categories <= 20:
185
- colors1 = plt.cm.tab20(np.linspace(0, 1, min(num_categories, 20)))
186
- colors = colors1[:num_categories]
187
- else:
188
- # For large number of categories, combine multiple distinct colormaps
189
- colors1 = plt.cm.tab20(np.linspace(0, 1, 20))
190
- colors2 = plt.cm.Set3(np.linspace(0, 1, 12))
191
- colors3 = plt.cm.Pastel1(np.linspace(0, 1, 9))
192
- colors4 = plt.cm.Paired(np.linspace(0, 1, 12))
193
-
194
- # Combine and take needed number of colors
195
- all_colors = np.vstack([colors1, colors2, colors3, colors4])
196
- # Shuffle the colors to ensure adjacent categories have distinct colors
197
- np.random.seed(42) # For consistency
198
- np.random.shuffle(all_colors)
199
- colors = all_colors[:num_categories]
200
-
201
- color_map = {category: mcolors.to_hex(color[:3])
202
- for category, color in zip(unique_categories, colors)}
181
+ def generate_distinct_colors(n):
182
+ """Generate visually distinct, bright colors with maximum contrast"""
183
+ if n <= 12:
184
+ # Use carefully selected high-contrast colors for small sets
185
+ base_colors = [
186
+ '#FF0000', # Bright Red
187
+ '#0066FF', # Bright Blue
188
+ '#00CC00', # Bright Green
189
+ '#FF8800', # Bright Orange
190
+ '#8800FF', # Bright Purple
191
+ '#FFFF00', # Bright Yellow
192
+ '#FF0088', # Bright Pink
193
+ '#00FFFF', # Bright Cyan
194
+ '#88FF00', # Bright Lime
195
+ '#FF4400', # Red-Orange
196
+ '#0088FF', # Sky Blue
197
+ '#CC00FF' # Magenta
198
+ ]
199
+ return base_colors[:n]
200
+ else:
201
+ # For larger sets, use HSV color space for maximum separation
202
+ colors = []
203
+ import colorsys
204
+ for i in range(n):
205
+ hue = (i * 360 / n) % 360
206
+ # Alternate saturation and value to create more distinction
207
+ sat = 0.85 if i % 2 == 0 else 0.95
208
+ val = 0.95 if i % 3 != 0 else 0.85
209
+
210
+ # Convert HSV to RGB
211
+ rgb = colorsys.hsv_to_rgb(hue/360, sat, val)
212
+ hex_color = '#{:02x}{:02x}{:02x}'.format(
213
+ int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255)
214
+ )
215
+ colors.append(hex_color)
216
+ return colors
217
+
218
+ # Generate the enhanced color palette
219
+ colors = generate_distinct_colors(num_categories)
220
+ color_map = dict(zip(unique_categories, colors))
203
221
 
204
222
  # Node size handling
205
223
  node_dict = {node: 30 if identity_dict[node] == 'Edge' else 100
@@ -225,11 +243,11 @@ def show_identity_network(excel_file_path, node_identities, geometric=False, geo
225
243
  # Create separate axes for the graph and legend
226
244
  graph_ax = plt.gca()
227
245
 
228
- # Draw the network
246
+ # Draw the network with enhanced font styling
229
247
  node_colors = [color_map[identity_dict[node]] for node in G.nodes()]
230
248
  nx.draw(G, pos, ax=graph_ax, with_labels=True, font_color='black',
231
249
  font_weight='bold', node_size=node_sizes_list,
232
- node_color=node_colors, alpha=0.8, font_size=12)
250
+ node_color=node_colors, alpha=0.8, font_size=11, font_family='sans-serif')
233
251
 
234
252
  # Create custom legend with multiple columns if needed
235
253
  legend_handles = [Patch(color=color, label=category)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.7.8
3
+ Version: 0.8.0
4
4
  Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
5
5
  Author-email: Liam McLaughlin <liamm@wustl.edu>
6
6
  Project-URL: Documentation, https://nettracer3d.readthedocs.io/en/latest/
@@ -73,14 +73,11 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
73
73
 
74
74
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
75
75
 
76
- -- Version 0.7.8 (and 0.7.7) Updates --
77
-
78
- * Bug Fixes
79
- * Added the excel helper loader for better automated loading from QuPath exports specifically
80
- * Added the ability to cluster communities into broader neighborhoods (with KMeans) based on their compositions.
81
- * Added heatmap and UMAP graph displays based on community compositions.
82
- * Added the ability to show heatmaps of nodes based on their density within their communities
83
- * Added the ability to cluster nodes into communities based on spatial grouping in arbitrarily-sized cells (rather than just using the network)
84
- * Added function to crop the current image
85
- * More options under 'Modify Network'
86
- * 'Show 3D' method now can render a bounding box.
76
+ -- Version 0.8.0 Updates --
77
+
78
+ * Added ability to threshold nodes by degree.
79
+ * Improved image viewer window performance.
80
+ * Bug fixes and a few optimizations.
81
+ * Added ability to 'merge node identities' which just uses the nodes image as a reference for collecting 'identity' information from a group of other images - ie can use with cell nuclei (DAPI) to see what markers from the same imaging session overlap.
82
+ * Added ability to search for specific nodes directly in the nodes image with 'shift + f' or right click.
83
+
@@ -0,0 +1,23 @@
1
+ nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ nettracer3d/community_extractor.py,sha256=ZOz97Au4k7dHK8azarWQtxCPyvwzGmDHNL8kTIC9by8,22670
3
+ nettracer3d/excelotron.py,sha256=lS5vnpoOGZWp7fdqVpTPqeC-mUKrfwDrWHfx4PQ7Uzg,71384
4
+ nettracer3d/modularity.py,sha256=O9OeKbjD3v6gSFz9K2GzP6LsxlpQaPfeJbM1pyIEigw,21788
5
+ nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
6
+ nettracer3d/neighborhoods.py,sha256=kkKR8m6Gjw34cDd_mytAIwLxqvuNBtQb2hU4JuBY9pI,12301
7
+ nettracer3d/nettracer.py,sha256=494nHDmdrdfecTAShbXc0eFE2tG6WKJtEqKvJyt4sh4,227141
8
+ nettracer3d/nettracer_gui.py,sha256=Pc_t5pDk0P4gpyC1axx37JJX6EpMvXdj0UHbqjqENrQ,501757
9
+ nettracer3d/network_analysis.py,sha256=h-5yzUWdE0hcWYy8wcBA5LV1bRhdqiMnKbQLrRzb1Sw,41443
10
+ nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
11
+ nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
12
+ nettracer3d/proximity.py,sha256=hPmTPFGUziPMVwfWRLVV9gUjqSL7nzLD6WAVLekvxbE,28545
13
+ nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
14
+ nettracer3d/segmenter.py,sha256=VatOSpc41lxhPuYLTTejCxG1CcwP5hwiQ3ZFK9OBavA,60115
15
+ nettracer3d/segmenter_GPU.py,sha256=sFVmz_cYIVOQqnfFV3peK9hzb6IoIV5WDQHH9Lws96I,53915
16
+ nettracer3d/simple_network.py,sha256=dkG4jpc4zzdeuoaQobgGfL3PNo6N8dGKQ5hEEubFIvA,9947
17
+ nettracer3d/smart_dilate.py,sha256=DOEOQq9ig6-AO4MpqAG0CqrGDFqw5_UBeqfSedqHk28,25933
18
+ nettracer3d-0.8.0.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
19
+ nettracer3d-0.8.0.dist-info/METADATA,sha256=2bK3auAT6Xr7y_VDBaZE_cB4dgShYtF0qrIzcuTDflU,4605
20
+ nettracer3d-0.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ nettracer3d-0.8.0.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
22
+ nettracer3d-0.8.0.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
23
+ nettracer3d-0.8.0.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- nettracer3d/community_extractor.py,sha256=BrONCLRLYUdMfLe_018AQi0k0J7xwVahc_lmsOO5Pwo,23086
3
- nettracer3d/excelotron.py,sha256=lS5vnpoOGZWp7fdqVpTPqeC-mUKrfwDrWHfx4PQ7Uzg,71384
4
- nettracer3d/modularity.py,sha256=O9OeKbjD3v6gSFz9K2GzP6LsxlpQaPfeJbM1pyIEigw,21788
5
- nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
6
- nettracer3d/neighborhoods.py,sha256=kkKR8m6Gjw34cDd_mytAIwLxqvuNBtQb2hU4JuBY9pI,12301
7
- nettracer3d/nettracer.py,sha256=M1KFIPg7WCzm8BXQOreuEVhgjg0PpLKRg4Y88DyVuK8,225843
8
- nettracer3d/nettracer_gui.py,sha256=WTcN-tOk4vzDLhnVN4un5PEkC90GDp3sxZZhgLifMOM,468787
9
- nettracer3d/network_analysis.py,sha256=h-5yzUWdE0hcWYy8wcBA5LV1bRhdqiMnKbQLrRzb1Sw,41443
10
- nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
11
- nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
12
- nettracer3d/proximity.py,sha256=5n8qxqxmmMtq5bqVpSkqw3EefuZIyGdLybVs18D3ZNg,27996
13
- nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
14
- nettracer3d/segmenter.py,sha256=BD9vxnblDKXfmR8hLP_iVqqfVngH6opz4Q7V6sxc2KM,60062
15
- nettracer3d/segmenter_GPU.py,sha256=Fqr0Za6X2ss4rfaziqOhvhBfbGDPHkHw6fVxs39lZaU,53862
16
- nettracer3d/simple_network.py,sha256=Ft_81VhVQ3rqoXvuYnsckXuxCcQSJfakhOfkFaclxZY,9340
17
- nettracer3d/smart_dilate.py,sha256=DOEOQq9ig6-AO4MpqAG0CqrGDFqw5_UBeqfSedqHk28,25933
18
- nettracer3d-0.7.8.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
19
- nettracer3d-0.7.8.dist-info/METADATA,sha256=GFylr691RVFXgRMrrEhOEW6ySL5vUW-8-bK8qQ4hr9A,4797
20
- nettracer3d-0.7.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
- nettracer3d-0.7.8.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
22
- nettracer3d-0.7.8.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
23
- nettracer3d-0.7.8.dist-info/RECORD,,