@@ -498,6 +498,8 @@ def _get_colors_for_categorical_obs(categories: Sequence[Union[str, int]]) -> li
498
498
499
499
500
500
Palette_t = Optional [Union [str , ListedColormap ]]
501
+ from matplotlib .colors import ListedColormap , to_hex , to_rgba
502
+ import matplotlib .pyplot as plt
501
503
502
504
503
505
def _get_palette (
@@ -509,15 +511,15 @@ def _get_palette(
509
511
) -> Mapping [str , str ] | None :
510
512
if palette is None :
511
513
try :
512
- palette = adata .uns [Key . uns . colors ( cluster_key ) ] # type: ignore[arg-type]
514
+ palette = adata .uns [f" { cluster_key } _colors" ] # type: ignore[arg-type]
513
515
if len (palette ) != len (categories ):
514
516
raise ValueError (
515
517
f"Expected palette to be of length `{ len (categories )} `, found `{ len (palette )} `. "
516
518
+ f"Removing the colors in `adata.uns` with `adata.uns.pop('{ cluster_key } _colors')` may help."
517
519
)
518
520
return {cat : to_hex (to_rgba (col )[:3 ] + (alpha ,), keep_alpha = True ) for cat , col in zip (categories , palette )}
519
521
except KeyError as e :
520
- logg . error ( f"Unable to fetch palette, reason: { e } . Using `None`." )
522
+ print ( e )
521
523
return None
522
524
523
525
len_cat = len (categories )
@@ -530,3 +532,27 @@ def _get_palette(
530
532
raise TypeError (f"Palette is { type (palette )} but should be string or `ListedColormap`." )
531
533
532
534
return dict (zip (categories , palette ))
535
+
536
+
537
+ def _maybe_set_colors (
538
+ source : AnnData , target : AnnData , key : str , palette : str | ListedColormap | Cycler | Sequence [Any ] | None = None
539
+ ) -> None :
540
+ color_key = f"{ key } _colors"
541
+ from scanpy .plotting ._utils import add_colors_for_categorical_sample_annotation
542
+
543
+ # this is insane, basically the version copied here was from napari
544
+ # in napari is modified because we have to do some tricks to plot the categorical values
545
+ # hence it requires the argument vec. But here we don't, so am re importing the original one
546
+ # from scanpy here.
547
+ # this is a testament to how broken the categorical color handling is in the scanpy ecosystem and
548
+ # to the fact that, because I've never fixed it, an embarassing amount of intellectual debt has
549
+ # been accumulated.
550
+
551
+ try :
552
+ if palette is not None :
553
+ raise KeyError ("Unable to copy the palette when there was other explicitly specified." )
554
+ target .uns [color_key ] = source .uns [color_key ]
555
+ except KeyError :
556
+ if isinstance (palette , ListedColormap ): # `scanpy` requires it
557
+ palette = cycler (color = palette .colors )
558
+ add_colors_for_categorical_sample_annotation (target , key = key , force_update_colors = True , palette = palette )
0 commit comments