1515import matplotlib .ticker
1616import numpy as np
1717import pandas as pd
18- import scanpy as sc
1918import spatialdata as sd
2019import xarray as xr
21- from anndata import AnnData
2220from matplotlib import patheffects
2321from matplotlib .cm import ScalarMappable
2422from matplotlib .colors import Colormap , ListedColormap , Normalize
2523from scanpy ._settings import settings as sc_settings
2624from scanpy .plotting ._tools .scatterplots import _add_categorical_legend
2725from spatialdata import get_extent , get_values
28- from spatialdata ._core .query .relational_query import match_table_to_element
2926from spatialdata .models import PointsModel , ShapesModel , get_table_keys
3027from spatialdata .transformations import set_transformation
3128from spatialdata .transformations .transformations import Identity
3835 _get_colors_for_categorical_obs ,
3936 _get_linear_colormap ,
4037 _map_color_seg ,
41- _maybe_set_colors ,
4238 _prepare_cmap_norm ,
4339 _resolve_continuous_norm ,
4440 resolve_color ,
@@ -333,7 +329,6 @@ def _add_legend_and_colorbar(
333329 ax : matplotlib .axes .SubplotBase ,
334330 cax : ScalarMappable | None ,
335331 fig_params : FigParams ,
336- adata : AnnData | None ,
337332 col_for_color : str | None ,
338333 color_spec : ColorSpec ,
339334 palette : ListedColormap | list [str ] | None ,
@@ -387,7 +382,6 @@ def _add_legend_and_colorbar(
387382 ax = ax ,
388383 cax = cax ,
389384 fig_params = fig_params ,
390- adata = adata ,
391385 value_to_plot = col_for_color ,
392386 color_source_vector = color_source_vector ,
393387 color_vector = color_vector ,
@@ -755,7 +749,6 @@ def _draw_centroids(xy: np.ndarray, radius: float | None = None) -> None:
755749 color_spec = color_spec ,
756750 norm = norm ,
757751 na_color = render_params .cmap_params .na_color ,
758- adata = table ,
759752 col_for_color = col_for_color ,
760753 palette = palette ,
761754 fig_params = fig_params ,
@@ -1025,7 +1018,6 @@ def _draw_centroids(xy: np.ndarray, radius: float | None = None) -> None:
10251018 ax = ax ,
10261019 cax = cax ,
10271020 fig_params = fig_params ,
1028- adata = table ,
10291021 col_for_color = col_for_color ,
10301022 color_spec = color_spec ,
10311023 palette = palette ,
@@ -1110,7 +1102,6 @@ def _render_centroids_as_points(
11101102 color_spec : ColorSpec ,
11111103 norm : Normalize | None ,
11121104 na_color : Any ,
1113- adata : AnnData | None ,
11141105 col_for_color : str | None ,
11151106 palette : Any ,
11161107 fig_params : FigParams ,
@@ -1170,7 +1161,6 @@ def _render_centroids_as_points(
11701161 ax = ax ,
11711162 cax = cax ,
11721163 fig_params = fig_params ,
1173- adata = adata ,
11741164 col_for_color = col_for_color ,
11751165 color_spec = color_spec ,
11761166 palette = palette ,
@@ -1382,50 +1372,15 @@ def _render_points(
13821372 else points_pd_with_color
13831373 )
13841374
1385- # we construct an anndata to hack the plotting functions
1386- if table_name is None :
1387- adata = AnnData (
1388- X = points [["x" , "y" ]].values ,
1389- obs = points [coords ],
1390- dtype = points [["x" , "y" ]].values .dtype ,
1391- )
1392- else :
1393- matched_table = match_table_to_element (sdata = sdata , element_name = element , table_name = table_name )
1394- adata_obs = matched_table .obs .copy ()
1395- # if the points are colored by values in X (or a different layer), add the values to obs
1396- if col_for_color in matched_table .var_names :
1397- if table_layer is None :
1398- adata_obs [col_for_color ] = matched_table [:, col_for_color ].X .flatten ()
1399- else :
1400- adata_obs [col_for_color ] = matched_table [:, col_for_color ].layers [table_layer ].flatten ()
1401- adata = AnnData (
1402- X = points [["x" , "y" ]].values ,
1403- obs = adata_obs ,
1404- dtype = points [["x" , "y" ]].values .dtype ,
1405- uns = matched_table .uns ,
1406- )
1407- sdata_filt [table_name ] = adata
1408-
1409- # we can modify the sdata because of dealing with a copy
1375+ # Color (from a points column, table obs, or table var/X) is already materialized on `points` via
1376+ # the get_values merge above; coordinates and the legend come straight from `points`/`color_spec`,
1377+ # so no AnnData round-trip is needed. resolve_color reads the original table (kept in sdata_filt)
1378+ # for any user-defined uns palette.
14101379
14111380 # Convert back to dask dataframe to modify sdata
14121381 transformation_in_cs = sdata_filt .points [element ].attrs ["transform" ][coordinate_system ]
14131382 _reparse_points (sdata_filt , element , points_for_model , transformation_in_cs , coordinate_system , col_for_color )
14141383
1415- if col_for_color is not None :
1416- assert isinstance (col_for_color , str )
1417- cols = sc .get .obs_df (adata , [col_for_color ])
1418- # maybe set color based on type
1419- if isinstance (cols [col_for_color ].dtype , pd .CategoricalDtype ):
1420- uns_color_key = f"{ col_for_color } _colors"
1421- if uns_color_key in adata .uns :
1422- _maybe_set_colors (
1423- source = adata ,
1424- target = adata ,
1425- key = col_for_color ,
1426- palette = palette ,
1427- )
1428-
14291384 # when user specified a single color, we emulate the form of `na_color` and use it
14301385 default_color = (
14311386 render_params .color if col_for_color is None and color is not None else render_params .cmap_params .na_color
@@ -1478,9 +1433,8 @@ def _render_points(
14781433 color_spec = color_spec .filter (keep )
14791434 if int (keep .sum ()) == 0 :
14801435 return
1481- # filter the materialized points, adata, and re-register in sdata_filt
1436+ # filter the materialized points and re-register in sdata_filt
14821437 points = points [keep ].reset_index (drop = True )
1483- adata = adata [keep ]
14841438 _reparse_points (sdata_filt , element , points , transformation_in_cs , coordinate_system , col_for_color )
14851439
14861440 color_spec = color_spec .apply_transfunc (render_params .transfunc )
@@ -1550,8 +1504,8 @@ def _render_points(
15501504 update_parameters = not _mpl_ax_contains_elements (ax )
15511505 cax = _scatter_points (
15521506 ax ,
1553- adata [:, 0 ]. X . flatten (),
1554- adata [:, 1 ]. X . flatten (),
1507+ points [ "x" ]. to_numpy (),
1508+ points [ "y" ]. to_numpy (),
15551509 color_spec .color_vector ,
15561510 size = render_params .size ,
15571511 cmap = render_params .cmap_params .cmap ,
@@ -1570,7 +1524,6 @@ def _render_points(
15701524 ax = ax ,
15711525 cax = cax ,
15721526 fig_params = fig_params ,
1573- adata = adata ,
15741527 col_for_color = col_for_color ,
15751528 color_spec = color_spec ,
15761529 palette = None ,
@@ -2409,7 +2362,6 @@ def _render_labels(
24092362 ),
24102363 norm = render_params .cmap_params .fresh_norm (), # ax.scatter autoscales in place; don't mutate the shared norm
24112364 na_color = na_color ,
2412- adata = table if table_name is not None else None ,
24132365 col_for_color = col_for_color ,
24142366 palette = palette ,
24152367 fig_params = fig_params ,
@@ -2510,7 +2462,6 @@ def _draw_labels(
25102462 ax = ax ,
25112463 cax = cax ,
25122464 fig_params = fig_params ,
2513- adata = table ,
25142465 col_for_color = col_for_color ,
25152466 color_spec = color_spec ,
25162467 palette = palette ,
0 commit comments