@@ -743,7 +743,6 @@ def _set_color_source_vec(
743
743
color = np .full (len (element ), value_to_plot )
744
744
return None , color , False
745
745
746
- # Figure out where to get the color from
747
746
origins = _locate_value (
748
747
value_key = value_to_plot ,
749
748
sdata = sdata ,
@@ -765,11 +764,9 @@ def _set_color_source_vec(
765
764
table_layer = table_layer ,
766
765
)[value_to_plot ]
767
766
768
- # Check what type of data we're dealing with
769
767
is_categorical = isinstance (color_source_vector .dtype , pd .CategoricalDtype )
770
768
is_numeric = pd .api .types .is_numeric_dtype (color_source_vector )
771
769
772
- # If it's numeric data, handle it appropriately
773
770
if is_numeric and not is_categorical :
774
771
if (
775
772
not isinstance (element , GeoDataFrame )
@@ -784,7 +781,6 @@ def _set_color_source_vec(
784
781
)
785
782
return None , color_source_vector , False
786
783
787
- # For non-numeric, non-categorical data (like strings), convert to categorical
788
784
if not is_categorical :
789
785
try :
790
786
color_source_vector = pd .Categorical (color_source_vector )
@@ -794,8 +790,6 @@ def _set_color_source_vec(
794
790
return None , color_source_vector , False
795
791
796
792
# At this point color_source_vector should be categorical
797
-
798
- # Look for predefined colors in the AnnData object
799
793
adata_with_colors = None
800
794
cluster_key = value_to_plot
801
795
@@ -812,12 +806,12 @@ def _set_color_source_vec(
812
806
first_table = next (iter (annotator_tables ))
813
807
adata_with_colors = sdata .tables [first_table ]
814
808
adata_with_colors .uns ["spatialdata_key" ] = first_table
809
+
815
810
# If no specific table is found, try using the default table
816
811
elif sdata .table is not None :
817
812
adata_with_colors = sdata .table
818
813
adata_with_colors .uns ["spatialdata_key" ] = "default_table"
819
814
820
- # Now generate the color mapping using the appropriate AnnData object and cluster_key
821
815
color_mapping = _get_categorical_color_mapping (
822
816
adata = adata_with_colors ,
823
817
cluster_key = cluster_key ,
@@ -868,7 +862,6 @@ def _map_color_seg(
868
862
) -> ArrayLike :
869
863
cell_id = np .array (cell_id )
870
864
871
- # Safely handle different types of color_vector
872
865
is_categorical = pd .api .types .is_categorical_dtype (getattr (color_vector , "dtype" , None ))
873
866
is_numeric = pd .api .types .is_numeric_dtype (getattr (color_vector , "dtype" , None ))
874
867
is_pandas_series = isinstance (color_vector , pd .Series )
@@ -962,31 +955,26 @@ def _generate_base_categorial_color_mapping(
962
955
na_color : ColorLike ,
963
956
cmap_params : CmapParams | None = None ,
964
957
) -> Mapping [str , str ]:
965
- color_key = f"{ cluster_key } _colors"
966
958
967
- # Break long string template into multiple lines to fix E501 error
959
+ color_key = f" { cluster_key } _colors"
968
960
color_found_in_uns_msg_template = (
969
961
"Using colors from '{cluster}_colors' in .uns slot of table '{table}' for plotting. "
970
962
"If this is unexpected, please delete the column from your AnnData object."
971
963
)
972
964
973
- # Check if we have a valid AnnData and if the color key exists in uns
974
965
if adata is not None and cluster_key is not None :
975
- # Check for direct color dictionary in uns (e.g., {'A': '#FF5733', 'B': '#3498DB'})
976
966
if cluster_key in adata .uns and isinstance (adata .uns [cluster_key ], dict ):
977
967
# We have a direct color mapping dictionary
978
968
color_dict = adata .uns [cluster_key ]
979
969
table_name = getattr (adata , "uns" , {}).get ("spatialdata_key" , "" )
980
970
if table_name :
981
- # Format the template with the actual values
982
971
logger .info (color_found_in_uns_msg_template .format (cluster = cluster_key , table = table_name ))
983
972
984
973
# Ensure all values are hex colors
985
974
for k , v in color_dict .items ():
986
975
if isinstance (v , str ) and not v .startswith ("#" ):
987
976
color_dict [k ] = to_hex (to_rgba (v ))
988
977
989
- # Add NA color if missing
990
978
categories = color_source_vector .categories .tolist ()
991
979
na_color_hex = to_hex (to_rgba (na_color )[:3 ])
992
980
@@ -996,24 +984,16 @@ def _generate_base_categorial_color_mapping(
996
984
colors = adata .uns [color_key ]
997
985
table_name = getattr (adata , "uns" , {}).get ("spatialdata_key" , "" )
998
986
if table_name :
999
- if isinstance (colors , dict ):
1000
- # Format the template with the actual values
1001
- logger .info (color_found_in_uns_msg_template .format (cluster = cluster_key , table = table_name ))
1002
- else :
1003
- # Format the template with the actual values
1004
- logger .info (color_found_in_uns_msg_template .format (cluster = cluster_key , table = table_name ))
987
+ logger .info (color_found_in_uns_msg_template .format (cluster = cluster_key , table = table_name ))
1005
988
1006
- # Ensure colors are in hex format
1007
989
if isinstance (colors , list ):
1008
990
colors = [to_hex (to_rgba (color )[:3 ]) for color in colors ]
1009
991
categories = color_source_vector .categories .tolist ()
1010
992
1011
- # Handle NaN values
1012
993
na_color_hex = to_hex (to_rgba (na_color )[:3 ])
1013
994
if "NaN" not in categories :
1014
995
categories .append ("NaN" )
1015
996
1016
- # Make sure we have enough colors
1017
997
if len (colors ) < len (categories ) - 1 : # -1 for NaN
1018
998
logger .warning (
1019
999
f"Not enough colors in { color_key } ({ len (colors )} ) for all categories ({ len (categories ) - 1 } ). "
@@ -1022,39 +1002,31 @@ def _generate_base_categorial_color_mapping(
1022
1002
# Extend with default colors or duplicate the last color
1023
1003
colors .extend ([na_color_hex ] * (len (categories ) - 1 - len (colors )))
1024
1004
1025
- # Create mapping with NaN color
1026
1005
return dict (zip (categories , colors + [na_color_hex ], strict = False ))
1027
1006
1028
1007
if isinstance (colors , np .ndarray ):
1029
- # Convert numpy array to list of hex colors
1030
1008
colors = [to_hex (to_rgba (color )[:3 ]) for color in colors ]
1031
1009
categories = color_source_vector .categories .tolist ()
1032
1010
1033
- # Handle NaN values
1034
1011
na_color_hex = to_hex (to_rgba (na_color )[:3 ])
1035
1012
if "NaN" not in categories :
1036
1013
categories .append ("NaN" )
1037
1014
1038
- # Make sure we have enough colors
1039
1015
if len (colors ) < len (categories ) - 1 : # -1 for NaN
1040
1016
logger .warning (
1041
1017
f"Not enough colors in { color_key } ({ len (colors )} ) for all categories ({ len (categories ) - 1 } ). "
1042
1018
"Some categories will use default colors."
1043
1019
)
1044
- # Extend with default colors
1045
1020
colors .extend ([na_color_hex ] * (len (categories ) - 1 - len (colors )))
1046
1021
1047
- # Create mapping with NaN color
1048
1022
return dict (zip (categories , colors + [na_color_hex ], strict = False ))
1049
1023
1050
- # Dictionary format - direct color mapping
1051
1024
if isinstance (colors , dict ):
1052
1025
# Ensure all values are hex colors
1053
1026
for k , v in colors .items ():
1054
1027
if isinstance (v , str ) and not v .startswith ("#" ):
1055
1028
colors [k ] = to_hex (to_rgba (v ))
1056
1029
1057
- # Get categories and handle NaN
1058
1030
categories = color_source_vector .categories .tolist ()
1059
1031
na_color_hex = to_hex (to_rgba (na_color )[:3 ])
1060
1032
@@ -1072,8 +1044,6 @@ def _generate_base_categorial_color_mapping(
1072
1044
1073
1045
return result
1074
1046
1075
- # If we reach here, we didn't find usable colors in uns, use default color mapping
1076
- logger .info (f"No colors found for '{ cluster_key } ' in AnnData.uns, using default colors" )
1077
1047
return _get_default_categorial_color_mapping (color_source_vector = color_source_vector , cmap_params = cmap_params )
1078
1048
1079
1049
0 commit comments