Skip to content

Commit 19a3fc9

Browse files
timtreisclaude
andcommitted
Fix col_for_color mutation during multi-table iteration, add unit tests
Avoid mutating col_for_color inside the auto-detect loop — resolve gene symbol to var_name only once after the table is selected. Add non-visual tests for the auto-detect path, missing symbol, and missing column error cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c2dd5d6 commit 19a3fc9

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/spatialdata_plot/pl/utils.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2819,7 +2819,7 @@ def _validate_col_for_column_table(
28192819
# Try gene_symbols fallback before discarding this table
28202820
if gene_symbols is not None:
28212821
try:
2822-
col_for_color = _resolve_gene_symbols(sdata[annotates], col_for_color, gene_symbols)
2822+
_resolve_gene_symbols(sdata[annotates], col_for_color, gene_symbols)
28232823
except KeyError:
28242824
tables.remove(annotates)
28252825
else:
@@ -2832,6 +2832,13 @@ def _validate_col_for_column_table(
28322832
table_name = next(iter(tables))
28332833
if len(tables) > 1:
28342834
logger.warning(f"Multiple tables contain column '{col_for_color}', using table '{table_name}'.")
2835+
# Resolve gene symbol to var_name using the selected table
2836+
if (
2837+
gene_symbols is not None
2838+
and col_for_color not in sdata[table_name].obs.columns
2839+
and col_for_color not in sdata[table_name].var_names
2840+
):
2841+
col_for_color = _resolve_gene_symbols(sdata[table_name], col_for_color, gene_symbols)
28352842
return col_for_color, table_name
28362843

28372844

tests/pl/test_render_shapes.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,35 @@ def test_plot_can_color_shapes_by_gene_symbols(self, sdata_blobs: SpatialData):
10191019
).pl.show()
10201020

10211021

1022+
def test_gene_symbols_auto_detect_table(sdata_blobs: SpatialData):
1023+
"""gene_symbols resolves correctly without explicit table_name (#247)."""
1024+
sdata_blobs["table"].obs["region"] = pd.Categorical(["blobs_circles"] * sdata_blobs["table"].n_obs)
1025+
sdata_blobs["table"].uns["spatialdata_attrs"]["region"] = "blobs_circles"
1026+
sdata_blobs["table"].var["gene_symbol"] = ["GeneA", "GeneB", "GeneC"]
1027+
# No table_name — auto-detect path
1028+
sdata_blobs.pl.render_shapes("blobs_circles", color="GeneA", gene_symbols="gene_symbol").pl.show()
1029+
plt.close("all")
1030+
1031+
1032+
def test_gene_symbols_missing_symbol_raises(sdata_blobs: SpatialData):
1033+
"""gene_symbols raises KeyError when the symbol is not found (#247)."""
1034+
sdata_blobs["table"].obs["region"] = pd.Categorical(["blobs_circles"] * sdata_blobs["table"].n_obs)
1035+
sdata_blobs["table"].uns["spatialdata_attrs"]["region"] = "blobs_circles"
1036+
sdata_blobs["table"].var["gene_symbol"] = ["GeneA", "GeneB", "GeneC"]
1037+
with pytest.raises(KeyError, match="Unable to locate color key 'NoSuchGene'"):
1038+
sdata_blobs.pl.render_shapes("blobs_circles", color="NoSuchGene", gene_symbols="gene_symbol").pl.show()
1039+
1040+
1041+
def test_gene_symbols_missing_column_raises(sdata_blobs: SpatialData):
1042+
"""gene_symbols raises KeyError when the var column doesn't exist (#247)."""
1043+
sdata_blobs["table"].obs["region"] = pd.Categorical(["blobs_circles"] * sdata_blobs["table"].n_obs)
1044+
sdata_blobs["table"].uns["spatialdata_attrs"]["region"] = "blobs_circles"
1045+
with pytest.raises(KeyError, match="not found in `adata.var`"):
1046+
sdata_blobs.pl.render_shapes(
1047+
"blobs_circles", color="GeneA", table_name="table", gene_symbols="nonexistent_col"
1048+
).pl.show()
1049+
1050+
10221051
def test_groups_na_color_none_no_match_shapes(sdata_blobs: SpatialData):
10231052
"""When no elements match the groups, the plot should render without error."""
10241053
sdata_blobs["blobs_polygons"]["cat_color"] = pd.Series(["a", "b", "a", "b", "a"], dtype="category")

0 commit comments

Comments
 (0)