risk-network 0.0.11__py3-none-any.whl → 0.0.12b1__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.
- risk/__init__.py +1 -1
- risk/annotations/__init__.py +4 -1
- risk/annotations/io.py +48 -47
- risk/annotations/nltk_setup.py +2 -1
- risk/log/__init__.py +1 -1
- risk/log/parameters.py +21 -22
- risk/neighborhoods/__init__.py +0 -1
- risk/neighborhoods/api.py +2 -2
- risk/neighborhoods/community.py +33 -4
- risk/neighborhoods/domains.py +6 -4
- risk/neighborhoods/neighborhoods.py +7 -1
- risk/neighborhoods/stats/__init__.py +13 -0
- risk/neighborhoods/stats/permutation/__init__.py +6 -0
- risk/{stats → neighborhoods/stats}/permutation/permutation.py +7 -4
- risk/{stats → neighborhoods/stats}/permutation/test_functions.py +2 -2
- risk/{stats/stat_tests.py → neighborhoods/stats/tests.py} +21 -13
- risk/network/__init__.py +0 -2
- risk/network/graph/__init__.py +0 -2
- risk/network/graph/api.py +2 -2
- risk/network/graph/graph.py +56 -57
- risk/{stats/significance.py → network/graph/stats.py} +2 -2
- risk/network/graph/summary.py +2 -3
- risk/network/io.py +151 -8
- risk/network/plotter/__init__.py +0 -2
- risk/network/plotter/api.py +1 -1
- risk/network/plotter/canvas.py +35 -35
- risk/network/plotter/contour.py +11 -12
- risk/network/plotter/labels.py +257 -246
- risk/network/plotter/plotter.py +2 -4
- risk/network/plotter/utils/colors.py +3 -0
- risk/risk.py +5 -5
- risk_network-0.0.12b1.dist-info/METADATA +122 -0
- risk_network-0.0.12b1.dist-info/RECORD +40 -0
- {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info}/WHEEL +1 -1
- risk/network/geometry.py +0 -150
- risk/stats/__init__.py +0 -15
- risk/stats/permutation/__init__.py +0 -6
- risk_network-0.0.11.dist-info/METADATA +0 -798
- risk_network-0.0.11.dist-info/RECORD +0 -41
- {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info/licenses}/LICENSE +0 -0
- {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info}/top_level.txt +0 -0
risk/network/plotter/labels.py
CHANGED
@@ -188,7 +188,7 @@ class Labels:
|
|
188
188
|
# Calculate the bounding box around the network
|
189
189
|
center, radius = calculate_bounding_box(self.graph.node_coordinates, radius_margin=scale)
|
190
190
|
# Calculate the best positions for labels
|
191
|
-
best_label_positions = _calculate_best_label_positions(
|
191
|
+
best_label_positions = self._calculate_best_label_positions(
|
192
192
|
filtered_domain_centroids, center, radius, offset
|
193
193
|
)
|
194
194
|
# Convert all domain colors to RGBA using the to_rgba helper function
|
@@ -207,7 +207,9 @@ class Labels:
|
|
207
207
|
# Split by special key TERM_DELIMITER to split annotation into multiple lines
|
208
208
|
annotations = filtered_domain_terms[domain].split(TERM_DELIMITER)
|
209
209
|
if fontcase is not None:
|
210
|
-
annotations = _apply_str_transformation(
|
210
|
+
annotations = self._apply_str_transformation(
|
211
|
+
words=annotations, transformation=fontcase
|
212
|
+
)
|
211
213
|
self.ax.annotate(
|
212
214
|
"\n".join(annotations),
|
213
215
|
xy=centroid,
|
@@ -281,6 +283,9 @@ class Labels:
|
|
281
283
|
found in arrow_alpha. Defaults to 1.0.
|
282
284
|
arrow_base_shrink (float, optional): Distance between the text and the base of the arrow. Defaults to 0.0.
|
283
285
|
arrow_tip_shrink (float, optional): Distance between the arrow tip and the centroid. Defaults to 0.0.
|
286
|
+
|
287
|
+
Raises:
|
288
|
+
ValueError: If no nodes are found in the network graph or if there are insufficient nodes to plot.
|
284
289
|
"""
|
285
290
|
# Check if nodes is a list of lists or a flat list
|
286
291
|
if any(isinstance(item, (list, tuple, np.ndarray)) for item in nodes):
|
@@ -627,7 +632,7 @@ class Labels:
|
|
627
632
|
]
|
628
633
|
|
629
634
|
# Use the combine_words function directly to handle word combinations and length constraints
|
630
|
-
compressed_terms = _combine_words(tuple(terms), max_chars_per_line, max_label_lines)
|
635
|
+
compressed_terms = self._combine_words(tuple(terms), max_chars_per_line, max_label_lines)
|
631
636
|
|
632
637
|
return compressed_terms
|
633
638
|
|
@@ -676,249 +681,255 @@ class Labels:
|
|
676
681
|
random_seed=random_seed,
|
677
682
|
)
|
678
683
|
|
684
|
+
def _combine_words(
|
685
|
+
self, words: List[str], max_chars_per_line: int, max_label_lines: int
|
686
|
+
) -> str:
|
687
|
+
"""Combine words to fit within the max_chars_per_line and max_label_lines constraints,
|
688
|
+
and separate the final output by TERM_DELIMITER for plotting.
|
679
689
|
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
690
|
+
Args:
|
691
|
+
words (List[str]): List of words to combine.
|
692
|
+
max_chars_per_line (int): Maximum number of characters in a line to display.
|
693
|
+
max_label_lines (int): Maximum number of lines in a label.
|
694
|
+
|
695
|
+
Returns:
|
696
|
+
str: String of combined words separated by ':' for line breaks.
|
697
|
+
"""
|
698
|
+
|
699
|
+
def try_combinations(words_batch: List[str]) -> List[str]:
|
700
|
+
"""Try to combine words within a batch and return them with combined words separated by ':'."""
|
701
|
+
combined_lines = []
|
702
|
+
i = 0
|
703
|
+
while i < len(words_batch):
|
704
|
+
current_word = words_batch[i]
|
705
|
+
combined_word = current_word # Start with the current word
|
706
|
+
# Try to combine more words if possible, and ensure the combination fits within max_length
|
707
|
+
for j in range(i + 1, len(words_batch)):
|
708
|
+
next_word = words_batch[j]
|
709
|
+
# Ensure that the combined word fits within the max_chars_per_line limit
|
710
|
+
if (
|
711
|
+
len(combined_word) + len(next_word) + 1 <= max_chars_per_line
|
712
|
+
): # +1 for space
|
713
|
+
combined_word = f"{combined_word} {next_word}"
|
714
|
+
i += 1 # Move past the combined word
|
715
|
+
else:
|
716
|
+
break # Stop combining if the length is exceeded
|
717
|
+
|
718
|
+
# Add the combined word only if it fits within the max_chars_per_line limit
|
719
|
+
if len(combined_word) <= max_chars_per_line:
|
720
|
+
combined_lines.append(combined_word) # Add the combined word
|
721
|
+
# Move to the next word
|
722
|
+
i += 1
|
723
|
+
|
724
|
+
# Stop if we've reached the max_label_lines limit
|
725
|
+
if len(combined_lines) >= max_label_lines:
|
726
|
+
break
|
727
|
+
|
728
|
+
return combined_lines
|
729
|
+
|
730
|
+
# Main logic: start with max_label_lines number of words
|
731
|
+
combined_lines = try_combinations(words[:max_label_lines])
|
732
|
+
remaining_words = words[max_label_lines:] # Remaining words after the initial batch
|
733
|
+
# Track words that have already been added
|
734
|
+
existing_words = set(" ".join(combined_lines).split())
|
735
|
+
|
736
|
+
# Continue pulling more words until we fill the lines
|
737
|
+
while remaining_words and len(combined_lines) < max_label_lines:
|
738
|
+
available_slots = max_label_lines - len(combined_lines)
|
739
|
+
words_to_add = [
|
740
|
+
word for word in remaining_words[:available_slots] if word not in existing_words
|
741
|
+
]
|
742
|
+
remaining_words = remaining_words[available_slots:]
|
743
|
+
# Update the existing words set
|
744
|
+
existing_words.update(words_to_add)
|
745
|
+
# Add to combined_lines only unique words
|
746
|
+
combined_lines += try_combinations(words_to_add)
|
747
|
+
|
748
|
+
# Join the final combined lines with TERM_DELIMITER, a special separator for line breaks
|
749
|
+
return TERM_DELIMITER.join(combined_lines[:max_label_lines])
|
750
|
+
|
751
|
+
def _calculate_best_label_positions(
|
752
|
+
self,
|
753
|
+
filtered_domain_centroids: Dict[str, Any],
|
754
|
+
center: np.ndarray,
|
755
|
+
radius: float,
|
756
|
+
offset: float,
|
757
|
+
) -> Dict[str, Any]:
|
758
|
+
"""Calculate and optimize label positions for clarity.
|
759
|
+
|
760
|
+
Args:
|
761
|
+
filtered_domain_centroids (Dict[str, Any]): Centroids of the filtered domains.
|
762
|
+
center (np.ndarray): The center coordinates for label positioning.
|
763
|
+
radius (float): The radius for positioning labels around the center.
|
764
|
+
offset (float): The offset distance from the radius for positioning labels.
|
765
|
+
|
766
|
+
Returns:
|
767
|
+
Dict[str, Any]: Optimized positions for labels.
|
768
|
+
"""
|
769
|
+
num_domains = len(filtered_domain_centroids)
|
770
|
+
# Calculate equidistant positions around the center for initial label placement
|
771
|
+
equidistant_positions = self._calculate_equidistant_positions_around_center(
|
772
|
+
center, radius, offset, num_domains
|
773
|
+
)
|
774
|
+
# Create a mapping of domains to their initial label positions
|
775
|
+
label_positions = dict(zip(filtered_domain_centroids.keys(), equidistant_positions))
|
776
|
+
# Optimize the label positions to minimize distance to domain centroids
|
777
|
+
return self._optimize_label_positions(label_positions, filtered_domain_centroids)
|
778
|
+
|
779
|
+
def _calculate_equidistant_positions_around_center(
|
780
|
+
self, center: np.ndarray, radius: float, label_offset: float, num_domains: int
|
781
|
+
) -> List[np.ndarray]:
|
782
|
+
"""Calculate positions around a center at equidistant angles.
|
783
|
+
|
784
|
+
Args:
|
785
|
+
center (np.ndarray): The central point around which positions are calculated.
|
786
|
+
radius (float): The radius at which positions are calculated.
|
787
|
+
label_offset (float): The offset added to the radius for label positioning.
|
788
|
+
num_domains (int): The number of positions (or domains) to calculate.
|
789
|
+
|
790
|
+
Returns:
|
791
|
+
List[np.ndarray]: List of positions (as 2D numpy arrays) around the center.
|
792
|
+
"""
|
793
|
+
# Calculate equidistant angles in radians around the center
|
794
|
+
angles = np.linspace(0, 2 * np.pi, num_domains, endpoint=False)
|
795
|
+
# Compute the positions around the center using the angles
|
796
|
+
return [
|
797
|
+
center + (radius + label_offset) * np.array([np.cos(angle), np.sin(angle)])
|
798
|
+
for angle in angles
|
733
799
|
]
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
Returns:
|
756
|
-
Dict[str, Any]: Optimized positions for labels.
|
757
|
-
"""
|
758
|
-
num_domains = len(filtered_domain_centroids)
|
759
|
-
# Calculate equidistant positions around the center for initial label placement
|
760
|
-
equidistant_positions = _calculate_equidistant_positions_around_center(
|
761
|
-
center, radius, offset, num_domains
|
762
|
-
)
|
763
|
-
# Create a mapping of domains to their initial label positions
|
764
|
-
label_positions = dict(zip(filtered_domain_centroids.keys(), equidistant_positions))
|
765
|
-
# Optimize the label positions to minimize distance to domain centroids
|
766
|
-
return _optimize_label_positions(label_positions, filtered_domain_centroids)
|
767
|
-
|
768
|
-
|
769
|
-
def _calculate_equidistant_positions_around_center(
|
770
|
-
center: np.ndarray, radius: float, label_offset: float, num_domains: int
|
771
|
-
) -> List[np.ndarray]:
|
772
|
-
"""Calculate positions around a center at equidistant angles.
|
773
|
-
|
774
|
-
Args:
|
775
|
-
center (np.ndarray): The central point around which positions are calculated.
|
776
|
-
radius (float): The radius at which positions are calculated.
|
777
|
-
label_offset (float): The offset added to the radius for label positioning.
|
778
|
-
num_domains (int): The number of positions (or domains) to calculate.
|
779
|
-
|
780
|
-
Returns:
|
781
|
-
List[np.ndarray]: List of positions (as 2D numpy arrays) around the center.
|
782
|
-
"""
|
783
|
-
# Calculate equidistant angles in radians around the center
|
784
|
-
angles = np.linspace(0, 2 * np.pi, num_domains, endpoint=False)
|
785
|
-
# Compute the positions around the center using the angles
|
786
|
-
return [
|
787
|
-
center + (radius + label_offset) * np.array([np.cos(angle), np.sin(angle)])
|
788
|
-
for angle in angles
|
789
|
-
]
|
790
|
-
|
791
|
-
|
792
|
-
def _optimize_label_positions(
|
793
|
-
best_label_positions: Dict[str, Any], domain_centroids: Dict[str, Any]
|
794
|
-
) -> Dict[str, Any]:
|
795
|
-
"""Optimize label positions around the perimeter to minimize total distance to centroids.
|
796
|
-
|
797
|
-
Args:
|
798
|
-
best_label_positions (Dict[str, Any]): Initial positions of labels around the perimeter.
|
799
|
-
domain_centroids (Dict[str, Any]): Centroid positions of the domains.
|
800
|
-
|
801
|
-
Returns:
|
802
|
-
Dict[str, Any]: Optimized label positions.
|
803
|
-
"""
|
804
|
-
while True:
|
805
|
-
improvement = False # Start each iteration assuming no improvement
|
806
|
-
# Iterate through each pair of labels to check for potential improvements
|
807
|
-
for i in range(len(domain_centroids)):
|
808
|
-
for j in range(i + 1, len(domain_centroids)):
|
809
|
-
# Calculate the current total distance
|
810
|
-
current_distance = _calculate_total_distance(best_label_positions, domain_centroids)
|
811
|
-
# Evaluate the total distance after swapping two labels
|
812
|
-
swapped_distance = _swap_and_evaluate(best_label_positions, i, j, domain_centroids)
|
813
|
-
# If the swap improves the total distance, perform the swap
|
814
|
-
if swapped_distance < current_distance:
|
815
|
-
labels = list(best_label_positions.keys())
|
816
|
-
best_label_positions[labels[i]], best_label_positions[labels[j]] = (
|
817
|
-
best_label_positions[labels[j]],
|
818
|
-
best_label_positions[labels[i]],
|
800
|
+
|
801
|
+
def _optimize_label_positions(
|
802
|
+
self, best_label_positions: Dict[str, Any], domain_centroids: Dict[str, Any]
|
803
|
+
) -> Dict[str, Any]:
|
804
|
+
"""Optimize label positions around the perimeter to minimize total distance to centroids.
|
805
|
+
|
806
|
+
Args:
|
807
|
+
best_label_positions (Dict[str, Any]): Initial positions of labels around the perimeter.
|
808
|
+
domain_centroids (Dict[str, Any]): Centroid positions of the domains.
|
809
|
+
|
810
|
+
Returns:
|
811
|
+
Dict[str, Any]: Optimized label positions.
|
812
|
+
"""
|
813
|
+
while True:
|
814
|
+
improvement = False # Start each iteration assuming no improvement
|
815
|
+
# Iterate through each pair of labels to check for potential improvements
|
816
|
+
for i in range(len(domain_centroids)):
|
817
|
+
for j in range(i + 1, len(domain_centroids)):
|
818
|
+
# Calculate the current total distance
|
819
|
+
current_distance = self._calculate_total_distance(
|
820
|
+
best_label_positions, domain_centroids
|
819
821
|
)
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
)
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
822
|
+
# Evaluate the total distance after swapping two labels
|
823
|
+
swapped_distance = self._swap_and_evaluate(
|
824
|
+
best_label_positions, i, j, domain_centroids
|
825
|
+
)
|
826
|
+
# If the swap improves the total distance, perform the swap
|
827
|
+
if swapped_distance < current_distance:
|
828
|
+
labels = list(best_label_positions.keys())
|
829
|
+
best_label_positions[labels[i]], best_label_positions[labels[j]] = (
|
830
|
+
best_label_positions[labels[j]],
|
831
|
+
best_label_positions[labels[i]],
|
832
|
+
)
|
833
|
+
improvement = True # Found an improvement, so continue optimizing
|
834
|
+
|
835
|
+
if not improvement:
|
836
|
+
break # Exit the loop if no improvement was found in this iteration
|
837
|
+
|
838
|
+
return best_label_positions
|
839
|
+
|
840
|
+
def _calculate_total_distance(
|
841
|
+
self, label_positions: Dict[str, Any], domain_centroids: Dict[str, Any]
|
842
|
+
) -> float:
|
843
|
+
"""Calculate the total distance from label positions to their domain centroids.
|
844
|
+
|
845
|
+
Args:
|
846
|
+
label_positions (Dict[str, Any]): Positions of labels around the perimeter.
|
847
|
+
domain_centroids (Dict[str, Any]): Centroid positions of the domains.
|
848
|
+
|
849
|
+
Returns:
|
850
|
+
float: The total distance from labels to centroids.
|
851
|
+
"""
|
852
|
+
total_distance = 0
|
853
|
+
# Iterate through each domain and calculate the distance to its centroid
|
854
|
+
for domain, pos in label_positions.items():
|
855
|
+
centroid = domain_centroids[domain]
|
856
|
+
total_distance += np.linalg.norm(centroid - pos)
|
857
|
+
|
858
|
+
return total_distance
|
859
|
+
|
860
|
+
def _swap_and_evaluate(
|
861
|
+
self,
|
862
|
+
label_positions: Dict[str, Any],
|
863
|
+
i: int,
|
864
|
+
j: int,
|
865
|
+
domain_centroids: Dict[str, Any],
|
866
|
+
) -> float:
|
867
|
+
"""Swap two labels and evaluate the total distance after the swap.
|
868
|
+
|
869
|
+
Args:
|
870
|
+
label_positions (Dict[str, Any]): Positions of labels around the perimeter.
|
871
|
+
i (int): Index of the first label to swap.
|
872
|
+
j (int): Index of the second label to swap.
|
873
|
+
domain_centroids (Dict[str, Any]): Centroid positions of the domains.
|
874
|
+
|
875
|
+
Returns:
|
876
|
+
float: The total distance after swapping the two labels.
|
877
|
+
"""
|
878
|
+
# Get the list of labels from the dictionary keys
|
879
|
+
labels = list(label_positions.keys())
|
880
|
+
swapped_positions = copy.deepcopy(label_positions)
|
881
|
+
# Swap the positions of the two specified labels
|
882
|
+
swapped_positions[labels[i]], swapped_positions[labels[j]] = (
|
883
|
+
swapped_positions[labels[j]],
|
884
|
+
swapped_positions[labels[i]],
|
885
|
+
)
|
886
|
+
# Calculate and return the total distance after the swap
|
887
|
+
return self._calculate_total_distance(swapped_positions, domain_centroids)
|
888
|
+
|
889
|
+
def _apply_str_transformation(
|
890
|
+
self, words: List[str], transformation: Union[str, Dict[str, str]]
|
891
|
+
) -> List[str]:
|
892
|
+
"""Apply a user-specified case transformation to each word in the list without appending duplicates.
|
893
|
+
|
894
|
+
Args:
|
895
|
+
words (List[str]): A list of words to transform.
|
896
|
+
transformation (Union[str, Dict[str, str]]): A single transformation (e.g., 'lower', 'upper', 'title', 'capitalize')
|
897
|
+
or a dictionary mapping cases ('lower', 'upper', 'title') to transformations (e.g., 'lower'='upper').
|
898
|
+
|
899
|
+
Returns:
|
900
|
+
List[str]: A list of transformed words with no duplicates.
|
901
|
+
"""
|
902
|
+
# Initialize a list to store transformed words
|
903
|
+
transformed_words = []
|
904
|
+
for word in words:
|
905
|
+
# Split word into subwords by space
|
906
|
+
subwords = word.split(" ")
|
907
|
+
transformed_subwords = []
|
908
|
+
# Apply transformation to each subword
|
909
|
+
for subword in subwords:
|
910
|
+
transformed_subword = subword # Start with the original subword
|
911
|
+
# If transformation is a string, apply it to all subwords
|
912
|
+
if isinstance(transformation, str):
|
913
|
+
if hasattr(subword, transformation):
|
914
|
+
transformed_subword = getattr(subword, transformation)()
|
915
|
+
|
916
|
+
# If transformation is a dictionary, apply case-specific transformations
|
917
|
+
elif isinstance(transformation, dict):
|
918
|
+
for case_type, transform in transformation.items():
|
919
|
+
if case_type == "lower" and subword.islower() and transform:
|
920
|
+
transformed_subword = getattr(subword, transform)()
|
921
|
+
elif case_type == "upper" and subword.isupper() and transform:
|
922
|
+
transformed_subword = getattr(subword, transform)()
|
923
|
+
elif case_type == "title" and subword.istitle() and transform:
|
924
|
+
transformed_subword = getattr(subword, transform)()
|
925
|
+
|
926
|
+
# Append the transformed subword to the list
|
927
|
+
transformed_subwords.append(transformed_subword)
|
928
|
+
|
929
|
+
# Rejoin the transformed subwords into a single string to preserve structure
|
930
|
+
transformed_word = " ".join(transformed_subwords)
|
931
|
+
# Only append if the transformed word is not already in the list
|
932
|
+
if transformed_word not in transformed_words:
|
933
|
+
transformed_words.append(transformed_word)
|
934
|
+
|
935
|
+
return transformed_words
|
risk/network/plotter/plotter.py
CHANGED
@@ -114,8 +114,7 @@ class Plotter(Canvas, Network, Contour, Labels):
|
|
114
114
|
|
115
115
|
return ax
|
116
116
|
|
117
|
-
|
118
|
-
def savefig(*args, pad_inches: float = 0.5, dpi: int = 100, **kwargs) -> None:
|
117
|
+
def savefig(self, *args, pad_inches: float = 0.5, dpi: int = 100, **kwargs) -> None:
|
119
118
|
"""Save the current plot to a file with additional export options.
|
120
119
|
|
121
120
|
Args:
|
@@ -132,8 +131,7 @@ class Plotter(Canvas, Network, Contour, Labels):
|
|
132
131
|
# Call plt.savefig with combined arguments
|
133
132
|
plt.savefig(*args, **kwargs)
|
134
133
|
|
135
|
-
|
136
|
-
def show(*args, **kwargs) -> None:
|
134
|
+
def show(self, *args, **kwargs) -> None:
|
137
135
|
"""Display the current plot.
|
138
136
|
|
139
137
|
Args:
|
@@ -356,6 +356,9 @@ def to_rgba(
|
|
356
356
|
|
357
357
|
Returns:
|
358
358
|
np.ndarray: Array of RGBA colors repeated `num_repeats` times, if applicable.
|
359
|
+
|
360
|
+
Raises:
|
361
|
+
ValueError: If the provided color format is invalid or cannot be converted to RGBA.
|
359
362
|
"""
|
360
363
|
|
361
364
|
def convert_to_rgba(c: Union[str, List, Tuple, np.ndarray]) -> np.ndarray:
|
risk/risk.py
CHANGED
@@ -3,12 +3,12 @@ risk/risk
|
|
3
3
|
~~~~~~~~~
|
4
4
|
"""
|
5
5
|
|
6
|
-
from risk.annotations import AnnotationsIO
|
6
|
+
from risk.annotations.io import AnnotationsIO
|
7
7
|
from risk.log import params, set_global_verbosity
|
8
|
-
from risk.neighborhoods import NeighborhoodsAPI
|
9
|
-
from risk.network import
|
10
|
-
from risk.network.
|
11
|
-
from risk.network.plotter import PlotterAPI
|
8
|
+
from risk.neighborhoods.api import NeighborhoodsAPI
|
9
|
+
from risk.network.graph.api import GraphAPI
|
10
|
+
from risk.network.io import NetworkIO
|
11
|
+
from risk.network.plotter.api import PlotterAPI
|
12
12
|
|
13
13
|
|
14
14
|
class RISK(NetworkIO, AnnotationsIO, NeighborhoodsAPI, GraphAPI, PlotterAPI):
|