@@ -1142,3 +1142,36 @@ def test_datashader_alpha_not_applied_twice(sdata_blobs: SpatialData):
11421142 "on top of the alpha already in the RGBA channels — causing double transparency."
11431143 )
11441144 plt .close (fig )
1145+
1146+
1147+ def test_render_shapes_color_with_conflicting_index_name ():
1148+ """render_shapes(color=...) must not crash when obs.index.name matches an existing column.
1149+
1150+ Regression test for https://github.com/scverse/spatialdata-plot/issues/441.
1151+ In Merfish data, the table's instance_key (e.g. 'EntityID') can appear as both
1152+ the obs index name and an obs column. Upstream spatialdata's join_spatialelement_table
1153+ calls reset_index() which raises ValueError when the index name collides with a column.
1154+ """
1155+ n = 10
1156+ rng = get_standard_RNG ()
1157+ circles = [Point (i , i ) for i in range (n )]
1158+ shapes_df = gpd .GeoDataFrame ({"geometry" : circles , "radius" : np .ones (n )})
1159+ shapes_df = ShapesModel .parse (shapes_df )
1160+
1161+ obs = pd .DataFrame (
1162+ {
1163+ "region" : pd .Categorical (["shapes" ] * n ),
1164+ "EntityID" : np .arange (n ),
1165+ "cell_type" : pd .Categorical (rng .choice (["A" , "B" , "C" ], n )),
1166+ }
1167+ )
1168+ table = AnnData (obs = obs )
1169+ table = TableModel .parse (table , region = "shapes" , region_key = "region" , instance_key = "EntityID" )
1170+
1171+ sdata = SpatialData (shapes = {"shapes" : shapes_df }, tables = {"table" : table })
1172+
1173+ # Introduce the conflicting state: index name == existing column name
1174+ sdata ["table" ].obs .index = pd .Index (np .arange (n ), name = "EntityID" )
1175+
1176+ # Should not raise ValueError: cannot insert EntityID, already exists
1177+ sdata .pl .render_shapes ("shapes" , color = "cell_type" , table_name = "table" ).pl .show ()
0 commit comments