|
62 | 62 | _Normalize = Normalize | abc.Sequence[Normalize] |
63 | 63 |
|
64 | 64 |
|
| 65 | +def _build_color_key_from_categorical(color_vector: object) -> list[str] | None: |
| 66 | + """Build a datashader ``color_key`` list from a categorical color vector. |
| 67 | +
|
| 68 | + Returns ``None`` when *color_vector* is not a :class:`pd.Categorical` or |
| 69 | + has no categories. Hex colours are stripped of their alpha channel; |
| 70 | + named colours (e.g. ``"red"``) are passed through unchanged. |
| 71 | + """ |
| 72 | + if type(color_vector) is not pd.core.arrays.categorical.Categorical: |
| 73 | + return None |
| 74 | + cat_values = color_vector.categories.values |
| 75 | + if len(cat_values) == 0: |
| 76 | + return None |
| 77 | + return [_hex_no_alpha(x) if isinstance(x, str) and x.startswith("#") else x for x in cat_values] |
| 78 | + |
| 79 | + |
65 | 80 | def _split_colorbar_params(params: dict[str, object] | None) -> tuple[dict[str, object], dict[str, object], str | None]: |
66 | 81 | """Split colorbar params into layout hints, Matplotlib kwargs, and label override.""" |
67 | 82 | layout: dict[str, object] = {} |
@@ -356,15 +371,7 @@ def _render_shapes( |
356 | 371 | agg = agg.where((agg <= norm.vmin) | (np.isnan(agg)), other=2) |
357 | 372 | agg = agg.where((agg != norm.vmin) | (np.isnan(agg)), other=0.5) |
358 | 373 |
|
359 | | - color_key = ( |
360 | | - [ |
361 | | - _hex_no_alpha(x) if isinstance(x, str) and x.startswith("#") else x |
362 | | - for x in color_vector.categories.values |
363 | | - ] |
364 | | - if (type(color_vector) is pd.core.arrays.categorical.Categorical) |
365 | | - and (len(color_vector.categories.values) > 0) |
366 | | - else None |
367 | | - ) |
| 374 | + color_key = _build_color_key_from_categorical(color_vector) |
368 | 375 |
|
369 | 376 | if color_by_categorical or col_for_color is None: |
370 | 377 | ds_cmap = None |
@@ -855,15 +862,7 @@ def _render_points( |
855 | 862 | agg = agg.where((agg <= norm.vmin) | (np.isnan(agg)), other=2) |
856 | 863 | agg = agg.where((agg != norm.vmin) | (np.isnan(agg)), other=0.5) |
857 | 864 |
|
858 | | - color_key: list[str] | None = ( |
859 | | - [ |
860 | | - _hex_no_alpha(x) if isinstance(x, str) and x.startswith("#") else x |
861 | | - for x in color_vector.categories.values |
862 | | - ] |
863 | | - if (type(color_vector) is pd.core.arrays.categorical.Categorical) |
864 | | - and (len(color_vector.categories.values) > 0) |
865 | | - else None |
866 | | - ) |
| 865 | + color_key = _build_color_key_from_categorical(color_vector) |
867 | 866 | if isinstance(color_vector[0], str) and ( |
868 | 867 | color_vector is not None and all(len(x) == 9 for x in color_vector) and color_vector[0][0] == "#" |
869 | 868 | ): |
|
0 commit comments