Skip to content

Commit 5868f14

Browse files
authored
Skip table fallback when coloring by element DataFrame column (#571)
1 parent 367204d commit 5868f14

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/spatialdata_plot/pl/utils.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,9 +1101,15 @@ def _set_color_source_vec(
11011101
processed = processed.reorder_categories(sorted(processed.categories))
11021102
color_source_vector = processed # convert, e.g., `pd.Series`
11031103

1104+
# When the value lives on the element's own DataFrame (origin="df"),
1105+
# there is no reason to look up a table for .uns colors.
1106+
value_from_element = origins[0].origin == "df"
1107+
11041108
# Use the provided table_name parameter, fall back to only one present
11051109
table_to_use: str | None
1106-
if table_name is not None and table_name in sdata.tables:
1110+
if value_from_element:
1111+
table_to_use = None
1112+
elif table_name is not None and table_name in sdata.tables:
11071113
table_to_use = table_name
11081114
elif table_name is not None and table_name not in sdata.tables:
11091115
logger.warning(f"Table '{table_name}' not found in `sdata.tables`. Falling back to default behavior.")
@@ -1120,14 +1126,18 @@ def _set_color_source_vec(
11201126

11211127
adata_for_mapping = sdata[table_to_use] if table_to_use is not None else None
11221128

1123-
# Check if custom colors exist in the table's .uns slot
1124-
if value_to_plot is not None and _has_colors_in_uns(sdata, table_name, value_to_plot):
1129+
# Check if custom colors exist in the resolved table's .uns slot
1130+
if (
1131+
value_to_plot is not None
1132+
and table_to_use is not None
1133+
and _has_colors_in_uns(sdata, table_to_use, value_to_plot)
1134+
):
11251135
# Extract colors directly from the table's .uns slot
11261136
# Convert Color to ColorLike (str) for the function
11271137
na_color_like: ColorLike = na_color.get_hex() if isinstance(na_color, Color) else na_color
11281138
color_mapping = _extract_colors_from_table_uns(
11291139
sdata=sdata,
1130-
table_name=table_name,
1140+
table_name=table_to_use,
11311141
col_to_colorby=value_to_plot,
11321142
color_source_vector=color_source_vector,
11331143
na_color=na_color_like,

tests/pl/test_render_points.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,3 +953,34 @@ def test_datashader_na_color_none_no_nan_overlay_points(sdata_blobs: SpatialData
953953
"datashader is still rendering an opaque NaN overlay despite na_color=None"
954954
)
955955
plt.close(fig)
956+
957+
958+
def test_no_table_fallback_warning_for_element_column(caplog):
959+
"""No spurious 'using X as fallback for color mapping' warning when coloring by an element column (#562)."""
960+
n = 50
961+
rng = np.random.default_rng(42)
962+
coords = pd.DataFrame({"x": rng.uniform(0, 100, n), "y": rng.uniform(0, 100, n)})
963+
coords["cell_type"] = pd.Categorical(rng.choice(["A", "B", "C"], n))
964+
points = PointsModel.parse(coords)
965+
966+
# Two tables so the multi-table fallback path is triggered
967+
obs1 = pd.DataFrame(index=pd.RangeIndex(10).astype(str))
968+
obs1["region"] = "s1"
969+
obs1["instance_id"] = range(10)
970+
table1 = AnnData(obs=obs1, X=np.zeros((10, 1)))
971+
table1 = TableModel.parse(table1, region="s1", region_key="region", instance_key="instance_id")
972+
973+
obs2 = pd.DataFrame(index=pd.RangeIndex(10).astype(str))
974+
obs2["region"] = "s2"
975+
obs2["instance_id"] = range(10)
976+
table2 = AnnData(obs=obs2, X=np.zeros((10, 1)))
977+
table2 = TableModel.parse(table2, region="s2", region_key="region", instance_key="instance_id")
978+
979+
sdata = SpatialData(
980+
points={"pts": points},
981+
tables={"RNA": table1, "protein": table2},
982+
)
983+
984+
with logger_no_warns(caplog, logger, match="fallback for color mapping"):
985+
sdata.pl.render_points("pts", color="cell_type").pl.show()
986+
plt.close("all")

0 commit comments

Comments
 (0)