nettracer3d 0.8.2__py3-none-any.whl → 0.8.3__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.

Potentially problematic release.


This version of nettracer3d might be problematic. Click here for more details.

@@ -517,21 +517,90 @@ def rgb_to_color_name(rgb: Tuple[int, int, int]) -> str:
517
517
  distance = np.sqrt(np.sum((rgb_array - np.array(color_rgb)) ** 2))
518
518
  if distance < min_distance:
519
519
  min_distance = distance
520
- closest_color = color_name + f" {str(rgb_array)}"
521
-
520
+ #closest_color = color_name + f" {str(rgb_array)}" # <- if we want RGB names
521
+ closest_color = color_name
522
+
522
523
  return closest_color
523
524
 
524
- def convert_node_colors_to_names(node_to_color: Dict[int, Tuple[int, int, int]]) -> Dict[int, str]:
525
+ def convert_node_colors_to_names(node_to_color: Dict[int, Tuple[int, int, int]],
526
+ show_legend: bool = True,
527
+ figsize: Tuple[int, int] = (10, 8),
528
+ save_path: str = None) -> Dict[int, str]:
525
529
  """
526
530
  Convert a dictionary of node-to-RGB mappings to node-to-color-name mappings.
531
+ Optionally displays a matplotlib legend showing the mappings.
527
532
 
528
533
  Args:
529
534
  node_to_color: Dictionary mapping node IDs to RGB tuples
535
+ show_legend: Whether to display the color legend plot
536
+ figsize: Figure size as (width, height) for the legend
537
+ save_path: Optional path to save the legend figure
530
538
 
531
539
  Returns:
532
540
  Dictionary mapping node IDs to color names
533
541
  """
534
- return {node: rgb_to_color_name(color) for node, color in node_to_color.items()}
542
+ # Convert colors to names
543
+ node_to_names = {node: rgb_to_color_name(color) for node, color in node_to_color.items()}
544
+
545
+ # Create legend if requested
546
+ if show_legend:
547
+ import matplotlib.pyplot as plt
548
+ from matplotlib.patches import Rectangle
549
+
550
+ num_entries = len(node_to_color)
551
+
552
+ # Calculate dynamic spacing based on number of entries
553
+ entry_height = 0.8
554
+ total_height = num_entries * entry_height + 1.5 # Extra space for title and margins
555
+
556
+ # Create figure and axis with proper scaling
557
+ fig, ax = plt.subplots(figsize=figsize)
558
+ ax.set_xlim(0, 10)
559
+ ax.set_ylim(0, total_height)
560
+ ax.axis('off')
561
+
562
+ # Title
563
+ ax.text(5, total_height - 0.5, 'Color Legend',
564
+ fontsize=16, fontweight='bold', ha='center')
565
+
566
+ # Sort nodes for consistent display
567
+ sorted_nodes = sorted(node_to_color.keys())
568
+
569
+ # Create legend entries
570
+ for i, node in enumerate(sorted_nodes):
571
+ y_pos = total_height - (i + 1) * entry_height - 0.8
572
+ rgb = node_to_color[node]
573
+ color_name = node_to_names[node]
574
+
575
+ # Normalize RGB values for matplotlib (0-1 range)
576
+ norm_rgb = tuple(c/255.0 for c in rgb)
577
+
578
+ # Draw color swatch (using actual RGB values)
579
+ swatch = Rectangle((1.0, y_pos - 0.15), 0.8, 0.3,
580
+ facecolor=norm_rgb, edgecolor='black', linewidth=1)
581
+ ax.add_patch(swatch)
582
+
583
+ # Node ID (exactly as it appears in dict keys)
584
+ ax.text(0.2, y_pos, str(node), fontsize=12, fontweight='bold',
585
+ va='center', ha='left')
586
+
587
+ # Color name (mapped name, nicely formatted)
588
+ ax.text(2.2, y_pos, color_name.replace('_', ' ').title(),
589
+ fontsize=11, va='center', ha='left')
590
+
591
+ # Add border around the legend
592
+ border = Rectangle((0.1, 0.1), 9.8, total_height - 0.2,
593
+ fill=False, edgecolor='gray', linewidth=2)
594
+ ax.add_patch(border)
595
+
596
+ plt.tight_layout()
597
+
598
+ if save_path:
599
+ plt.savefig(save_path, dpi=300, bbox_inches='tight')
600
+
601
+ plt.show()
602
+
603
+ return node_to_names
535
604
 
536
605
  def generate_distinct_colors(n_colors: int) -> List[Tuple[int, int, int]]:
537
606
  """
@@ -596,7 +665,7 @@ def assign_node_colors(node_list: List[int], labeled_array: np.ndarray) -> Tuple
596
665
 
597
666
  # Convert colors for naming
598
667
  node_to_color_rgb = {k: tuple(v[:3]) for k, v in node_to_color.items()}
599
- node_to_color_names = convert_node_colors_to_names(node_to_color_rgb)
668
+ node_to_color_names = convert_node_colors_to_names(node_to_color_rgb, show_legend = False)
600
669
 
601
670
  return rgba_array, node_to_color_names
602
671
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nettracer3d
3
- Version: 0.8.2
3
+ Version: 0.8.3
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/
@@ -107,11 +107,6 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
107
107
 
108
108
  NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
109
109
 
110
- -- Version 0.8.2 Updates --
110
+ -- Version 0.8.3 Updates --
111
111
 
112
- * Bug Fixes.
113
- * Improved some of the image viewer window features.
114
- * New option to zoom in on specific windows by clicking + dragging while in zoom mode.
115
- * Added more features to UMAP/community neighborhood clustering (optional DBSCAN clustering, results more robust to node distribution)
116
- * Made Napari and optional rather than core dependency.
117
- * Added Cellpose as an optional dependency.
112
+ * Added better color legend display
@@ -1,6 +1,6 @@
1
1
  nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  nettracer3d/cellpose_manager.py,sha256=qZpTxSkmPb38Pru8TmjJ88xxcD_wM02EfJB5Mw9Xx4Y,6021
3
- nettracer3d/community_extractor.py,sha256=oa4e0bAwUALDgu_QdBiqNNn1XrmOW3drD5bjwey81BI,25313
3
+ nettracer3d/community_extractor.py,sha256=08WWUO94ToZFglBU9X1L-T-WJuaIa-8t35-52kN4i6g,28167
4
4
  nettracer3d/excelotron.py,sha256=lS5vnpoOGZWp7fdqVpTPqeC-mUKrfwDrWHfx4PQ7Uzg,71384
5
5
  nettracer3d/modularity.py,sha256=O9OeKbjD3v6gSFz9K2GzP6LsxlpQaPfeJbM1pyIEigw,21788
6
6
  nettracer3d/morphology.py,sha256=jyDjYzrZ4LvI5jOyw8DLsxmo-i5lpqHsejYpW7Tq7Mo,19786
@@ -16,9 +16,9 @@ nettracer3d/segmenter.py,sha256=VatOSpc41lxhPuYLTTejCxG1CcwP5hwiQ3ZFK9OBavA,6011
16
16
  nettracer3d/segmenter_GPU.py,sha256=sFVmz_cYIVOQqnfFV3peK9hzb6IoIV5WDQHH9Lws96I,53915
17
17
  nettracer3d/simple_network.py,sha256=dkG4jpc4zzdeuoaQobgGfL3PNo6N8dGKQ5hEEubFIvA,9947
18
18
  nettracer3d/smart_dilate.py,sha256=DOEOQq9ig6-AO4MpqAG0CqrGDFqw5_UBeqfSedqHk28,25933
19
- nettracer3d-0.8.2.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
20
- nettracer3d-0.8.2.dist-info/METADATA,sha256=QlUhREQ7hy0wHfA8nKn6Qu_W-QONoGPSQY5yp9GEBYE,7112
21
- nettracer3d-0.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- nettracer3d-0.8.2.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
23
- nettracer3d-0.8.2.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
24
- nettracer3d-0.8.2.dist-info/RECORD,,
19
+ nettracer3d-0.8.3.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
20
+ nettracer3d-0.8.3.dist-info/METADATA,sha256=yVQGa_obriAzfkWCzXCS0EYtxBRD8UmHL8OWmFIxFJ8,6750
21
+ nettracer3d-0.8.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ nettracer3d-0.8.3.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
23
+ nettracer3d-0.8.3.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
24
+ nettracer3d-0.8.3.dist-info/RECORD,,