|
17 | 17 | from matplotlib.cm import ScalarMappable |
18 | 18 | from matplotlib.colors import ListedColormap, Normalize |
19 | 19 | from scanpy._settings import settings as sc_settings |
20 | | -from spatialdata import get_extent, get_values, join_spatialelement_table |
| 20 | +from spatialdata import get_extent, get_values, get_element_annotators, join_spatialelement_table |
21 | 21 | from spatialdata.models import PointsModel, ShapesModel, get_table_keys |
22 | 22 | from spatialdata.transformations import get_transformation, set_transformation |
23 | 23 | from spatialdata.transformations.transformations import Identity |
@@ -73,24 +73,36 @@ def _render_shapes( |
73 | 73 | col_for_color = render_params.col_for_color |
74 | 74 | groups = render_params.groups |
75 | 75 | table_layer = render_params.table_layer |
| 76 | + table_name = render_params.table_name |
76 | 77 |
|
77 | 78 | sdata_filt = sdata.filter_by_coordinate_system( |
78 | 79 | coordinate_system=coordinate_system, |
79 | 80 | filter_tables=bool(render_params.table_name), |
80 | 81 | ) |
81 | | - |
82 | | - if (table_name := render_params.table_name) is None: |
| 82 | + if table_name is None: |
83 | 83 | table = None |
84 | 84 | shapes = sdata_filt[element] |
85 | 85 | else: |
86 | | - element_dict, joined_table = join_spatialelement_table( |
87 | | - sdata, spatial_element_names=element, table_name=table_name, how="inner" |
88 | | - ) |
89 | | - sdata_filt[element] = shapes = element_dict[element] |
90 | | - joined_table.uns["spatialdata_attrs"]["region"] = ( |
91 | | - joined_table.obs[joined_table.uns["spatialdata_attrs"]["region_key"]].unique().tolist() |
92 | | - ) |
93 | | - sdata_filt[table_name] = table = joined_table |
| 86 | + # Check if the table actually annotates the element |
| 87 | + annotating_tables = get_element_annotators(sdata, element) |
| 88 | + if table_name not in annotating_tables: |
| 89 | + warnings.warn( |
| 90 | + f"Table '{table_name}' does not annotate element '{element}'", |
| 91 | + UserWarning, |
| 92 | + stacklevel=2, |
| 93 | + ) |
| 94 | + # Fall back to no table |
| 95 | + table = None |
| 96 | + shapes = sdata_filt[element] |
| 97 | + else: |
| 98 | + element_dict, joined_table = join_spatialelement_table( |
| 99 | + sdata, spatial_element_names=element, table_name=table_name, how="inner" |
| 100 | + ) |
| 101 | + sdata_filt[element] = shapes = element_dict[element] |
| 102 | + joined_table.uns["spatialdata_attrs"]["region"] = ( |
| 103 | + joined_table.obs[joined_table.uns["spatialdata_attrs"]["region_key"]].unique().tolist() |
| 104 | + ) |
| 105 | + sdata_filt[table_name] = table = joined_table |
94 | 106 |
|
95 | 107 | if ( |
96 | 108 | col_for_color is not None |
@@ -490,22 +502,37 @@ def _render_points( |
490 | 502 | dtype=points[["x", "y"]].values.dtype, |
491 | 503 | ) |
492 | 504 | else: |
493 | | - adata_obs = sdata_filt[table_name].obs |
494 | | - # if the points are colored by values in X (or a different layer), add the values to obs |
495 | | - if col_for_color in sdata_filt[table_name].var_names: |
496 | | - if table_layer is None: |
497 | | - adata_obs[col_for_color] = sdata_filt[table_name][:, col_for_color].X.flatten().copy() |
498 | | - else: |
499 | | - adata_obs[col_for_color] = sdata_filt[table_name][:, col_for_color].layers[table_layer].flatten().copy() |
500 | | - if groups is not None: |
501 | | - adata_obs = adata_obs[adata_obs[col_for_color].isin(groups)] |
502 | | - adata = AnnData( |
503 | | - X=points[["x", "y"]].values, |
504 | | - obs=adata_obs, |
505 | | - dtype=points[["x", "y"]].values.dtype, |
506 | | - uns=sdata_filt[table_name].uns, |
507 | | - ) |
508 | | - sdata_filt[table_name] = adata |
| 505 | + # Check if the table actually annotates the element |
| 506 | + annotating_tables = get_element_annotators(sdata, element) |
| 507 | + if table_name not in annotating_tables: |
| 508 | + warnings.warn( |
| 509 | + f"Table '{table_name}' does not annotate element '{element}'", |
| 510 | + UserWarning, |
| 511 | + stacklevel=2, |
| 512 | + ) |
| 513 | + # Fall back to no table |
| 514 | + adata = AnnData( |
| 515 | + X=points[["x", "y"]].values, |
| 516 | + obs=points[coords].reset_index(), |
| 517 | + dtype=points[["x", "y"]].values.dtype, |
| 518 | + ) |
| 519 | + else: |
| 520 | + adata_obs = sdata_filt[table_name].obs |
| 521 | + # if the points are colored by values in X (or a different layer), add the values to obs |
| 522 | + if col_for_color in sdata_filt[table_name].var_names: |
| 523 | + if table_layer is None: |
| 524 | + adata_obs[col_for_color] = sdata_filt[table_name][:, col_for_color].X.flatten().copy() |
| 525 | + else: |
| 526 | + adata_obs[col_for_color] = sdata_filt[table_name][:, col_for_color].layers[table_layer].flatten().copy() |
| 527 | + if groups is not None: |
| 528 | + adata_obs = adata_obs[adata_obs[col_for_color].isin(groups)] |
| 529 | + adata = AnnData( |
| 530 | + X=points[["x", "y"]].values, |
| 531 | + obs=adata_obs, |
| 532 | + dtype=points[["x", "y"]].values.dtype, |
| 533 | + uns=sdata_filt[table_name].uns, |
| 534 | + ) |
| 535 | + sdata_filt[table_name] = adata |
509 | 536 |
|
510 | 537 | # we can modify the sdata because of dealing with a copy |
511 | 538 |
|
@@ -1051,11 +1078,23 @@ def _render_labels( |
1051 | 1078 | instance_id = np.unique(label) |
1052 | 1079 | table = None |
1053 | 1080 | else: |
1054 | | - _, region_key, instance_key = get_table_keys(sdata[table_name]) |
1055 | | - table = sdata[table_name][sdata[table_name].obs[region_key].isin([element])] |
| 1081 | + # Check if the table actually annotates the element |
| 1082 | + annotating_tables = get_element_annotators(sdata, element) |
| 1083 | + if table_name not in annotating_tables: |
| 1084 | + warnings.warn( |
| 1085 | + f"Table '{table_name}' does not annotate element '{element}'", |
| 1086 | + UserWarning, |
| 1087 | + stacklevel=2, |
| 1088 | + ) |
| 1089 | + # Fall back to no table |
| 1090 | + instance_id = np.unique(label) |
| 1091 | + table = None |
| 1092 | + else: |
| 1093 | + _, region_key, instance_key = get_table_keys(sdata[table_name]) |
| 1094 | + table = sdata[table_name][sdata[table_name].obs[region_key].isin([element])] |
1056 | 1095 |
|
1057 | | - # get instance id based on subsetted table |
1058 | | - instance_id = np.unique(table.obs[instance_key].values) |
| 1096 | + # get instance id based on subsetted table |
| 1097 | + instance_id = np.unique(table.obs[instance_key].values) |
1059 | 1098 |
|
1060 | 1099 | _, trans_data = _prepare_transformation(label, coordinate_system, ax) |
1061 | 1100 |
|
|
0 commit comments