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