spatialdata-plot
spatialdata-plot copied to clipboard
render_shapes() fails to accept custom color palette but not when cropped to a certain size
import os as os
import glob
import numpy as np
import pandas as pd
import scanpy as sc
import anndata as ad
import matplotlib.pyplot as plt
import seaborn as sns
import spatialdata as sd
import spatialdata_plot as sd_plot
import zarr
from spatialdata import SpatialData, read_zarr
from spatialdata.transformations import Identity
import squidpy as sq
from spatialdata.models import Image2DModel, PointsModel, ShapesModel, TableModel
import dask.array as da
import dask.dataframe as dd
import tifffile
import geopandas as gpd
from shapely.geometry import Polygon
from spatialdata import bounding_box_query
def crop0(x):
return bounding_box_query(
x,
min_coordinate=[8000, 3000],
max_coordinate=[12000, 7000],
axes=("x", "y"),
target_coordinate_system="global",
)
crop0(sdata).pl.render_shapes(color="detailed_celltype_annotation",
groups=cells_detailed,
palette=colors_detailed).pl.show(
figsize=(12, 9),
legend_fontsize=14)
Where cells_detailed is a list of strings that match the categories in "detailed_celltype_annotation"
and colors_detailed is a list of hexcode strings that match cells_detailed
This returns the desired output
However
sdata.pl.render_shapes(color="detailed_celltype_annotation",
groups=cells_detailed,
palette=colors_detailed).pl.show(
figsize=(12, 9),
legend_fontsize=14)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[86], line 1
----> 1 sdata.pl.render_shapes(color="detailed_celltype_annotation",
2 groups=cells_detailed,
3 palette=colors_detailed).pl.show(
4 figsize=(12, 9),
5 legend_fontsize=14)
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:937, in PlotAccessor.show(self, coordinate_systems, legend_fontsize, legend_fontweight, legend_loc, legend_fontoutline, na_in_legend, colorbar, wspace, hspace, ncols, frameon, figsize, dpi, fig, title, share_extent, pad_extent, ax, return_ax, save)
932 wanted_elements, wanted_shapes_on_this_cs, wants_shapes = _get_wanted_render_elements(
933 sdata, wanted_elements, params_copy, cs, "shapes"
934 )
936 if wanted_shapes_on_this_cs:
--> 937 _render_shapes(
938 sdata=sdata,
939 render_params=params_copy,
940 coordinate_system=cs,
941 ax=ax,
942 fig_params=fig_params,
943 scalebar_params=scalebar_params,
944 legend_params=legend_params,
945 )
947 elif cmd == "render_points" and has_points:
948 wanted_elements, wanted_points_on_this_cs, wants_points = _get_wanted_render_elements(
949 sdata, wanted_elements, params_copy, cs, "points"
950 )
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/spatialdata_plot/pl/render.py:259, in _render_shapes(sdata, render_params, coordinate_system, ax, fig_params, scalebar_params, legend_params)
256 if isinstance(ds_cmap, str) and ds_cmap[0] == "#":
257 ds_cmap = ds_cmap[:-2]
--> 259 ds_result = ds.tf.shade(
260 agg,
261 cmap=ds_cmap,
262 color_key=color_key,
263 min_alpha=np.min([254, render_params.fill_alpha * 255]),
264 how="linear",
265 )
266 elif aggregate_with_reduction is not None: # to shut up mypy
267 ds_cmap = render_params.cmap_params.cmap
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/datashader/transfer_functions/__init__.py:725, in shade(agg, cmap, color_key, how, alpha, min_alpha, span, name, color_baseline, rescale_discrete_levels)
722 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name,
723 rescale_discrete_levels)
724 elif agg.ndim == 3:
--> 725 return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline,
726 rescale_discrete_levels)
727 else:
728 raise ValueError("agg must use 2D or 3D coordinates")
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/datashader/transfer_functions/__init__.py:383, in _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
379 if len(color_key) < len(cats):
380 raise ValueError(f"Insufficient colors provided ({len(color_key)}) for the categorical "
381 f"fields available ({len(cats)})")
--> 383 colors = [rgb(color_key[c]) for c in cats]
384 rs, gs, bs = map(array, zip(*colors))
386 # Reorient array (transposing the category dimension first)
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/datashader/transfer_functions/__init__.py:383, in <listcomp>(.0)
379 if len(color_key) < len(cats):
380 raise ValueError(f"Insufficient colors provided ({len(color_key)}) for the categorical "
381 f"fields available ({len(cats)})")
--> 383 colors = [rgb(color_key[c]) for c in cats]
384 rs, gs, bs = map(array, zip(*colors))
386 # Reorient array (transposing the category dimension first)
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/datashader/colors.py:116, in rgb(x)
114 if isinstance(x, str):
115 if x.startswith('#'):
--> 116 return hex_to_rgb(x)
117 elif x in color_lookup:
118 return hex_to_rgb(color_lookup[x])
File ~/.conda/envs/pca_env/lib/python3.10/site-packages/datashader/colors.py:91, in hex_to_rgb(x)
83 """Convert a color hexcode to an rgb tuple.
84
85 Example
(...)
88 (255, 255, 255)
89 """
90 if not (x.startswith('#') and len(x) == 7):
---> 91 raise ValueError("Invalid hex color")
92 x = x.strip('#')
93 try:
ValueError: Invalid hex color
I manually ran this code on my color palette and it returns no error: if not (x.startswith('#') and len(x) == 7)
The error occurs in any larger crop area and disappears in smaller crops. My goal here was to transfer my color palette from other plots to ensure a consistent coloring scheme. The only difference I can think of is that the cropped regions don't contain all of the celltypes in this shape and somehow that prevents raising this Error.