import scomv
import stlearn as st
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import cv2
import pandas as pd
import numpy as np
import anndata
import scanpy as sc
/Users/nomura/miniconda3/envs/sc-test310/lib/python3.10/site-packages/louvain/__init__.py:54: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  from pkg_resources import get_distribution, DistributionNotFound
/Users/nomura/miniconda3/envs/sc-test310/lib/python3.10/site-packages/numba/core/decorators.py:282: RuntimeWarning: nopython is set for njit and is ignored
  warnings.warn('nopython is set for njit and is ignored', RuntimeWarning)
/Users/nomura/miniconda3/envs/sc-test310/lib/python3.10/site-packages/stlearn/tl/cci/het.py:206: NumbaDeprecationWarning: The keyword argument 'nopython=False' was supplied. From Numba 0.59.0 the default is being changed to True and use of 'nopython=False' will raise a warning as the argument will have no effect. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  @jit(parallel=True, nopython=False)
# Download tutorial dataset
#!mkdir tutorial_data
#!mkdir tutorial_data/xenium_data
#!wget -P tutorial_data/xenium_data/ https://cf.10xgenomics.com/samples/xenium/preview/Xenium_FFPE_Human_Breast_Cancer_Rep1/Xenium_FFPE_Human_Breast_Cancer_Rep1_cell_feature_matrix.h5
#!wget -P tutorial_data/xenium_data/ https://cf.10xgenomics.com/samples/xenium/preview/Xenium_FFPE_Human_Breast_Cancer_Rep1/Xenium_FFPE_Human_Breast_Cancer_Rep1_cells.csv.gz
# Load Xenium data using stlearn
adata = st.ReadXenium(
    feature_cell_matrix_file="../tutorial_data/xenium_data/cell_feature_matrix.h5",
    cell_summary_file="../tutorial_data/xenium_data/cells.csv.gz",
    library_id="example data",
    image_path=None,
    scale=1,
    spot_diameter_fullres=10
)
Warning: Using default pixel size of 0.2125 microns. Consider providing experiment_xenium_file for accurate pixel size.
# Gridding at 10μm interval using stlearn
N_COL = int((adata.obs.imagecol.max() - adata.obs.imagecol.min()) / 10)
N_ROW = int((adata.obs.imagerow.max() - adata.obs.imagerow.min()) / 10)
grid = st.tl.cci.grid(adata, n_row=N_ROW, n_col=N_COL, n_cpus=10, verbose=False)
from scomv.preparation.skny_calc_distance import calculate_distance
## apply SKNY
grid = calculate_distance(
    grid, pos_marker_ls=['CDH1',"EPCAM"],
)
# Figure 2B
fig, ax = plt.subplots(figsize=(8, 6), dpi=150)
ax.imshow(cv2.cvtColor(grid.uns["marker_median_delineation"], cv2.COLOR_BGR2RGB),
          interpolation="nearest")
ax.axis("off")
plt.show()
../../_images/701857fb2219abb4fb0b1a1bb4e6dbf222ebe9f785c61a94ebb94f44aed4777e.png
import plotly.express as px
import plotly.io as pio
import cv2
import numpy as np

# Convert BGR (OpenCV) image to RGB for Plotly display
img = cv2.cvtColor(grid.uns["marker_median_delineation"], cv2.COLOR_BGR2RGB)

scale = 10  # spatial scaling factor

fig = px.imshow(img)

h, w = img.shape[:2]

# ---- Scale axis tick labels by a factor of 10 ----
step = 200
fig.update_xaxes(
    tickmode="array",
    tickvals=list(range(0, w, step)),
    ticktext=[str(v * scale) for v in range(0, w, step)]
)
fig.update_yaxes(
    tickmode="array",
    tickvals=list(range(0, h, step)),
    ticktext=[str(v * scale) for v in range(0, h, step)]
)

# ---- Create a full-resolution coordinate grid for hover display ----
# xx: scaled x-coordinates for each pixel (shape: h × w)
# yy: scaled y-coordinates for each pixel (shape: h × w)
xx = (np.arange(w)[None, :] * scale).repeat(h, axis=0)
yy = (np.arange(h)[:, None] * scale).repeat(w, axis=1)

# Stack into (h, w, 2) so hover can access scaled x and y
custom = np.dstack([xx, yy])

# ---- Override hover text to show scaled spatial coordinates ----
fig.update_traces(
    customdata=custom,
    hovertemplate="x: %{customdata[0]}<br>y: %{customdata[1]}<extra></extra>"
)

fig.update_layout(
    title="Figure 2B",
    xaxis_title="x",
    yaxis_title="y",
    height=700
)

# Use the notebook-connected renderer for interactive display
pio.renderers.default = "notebook_connected"

fig.show()

# ↓↓ Zooming and cropping are supported interactively ↓↓
# annotation each section to obs object
df_shotest = getattr(grid, "shortest")
df_grid = grid.to_df()

# extract grid info
df_grid = pd.merge(
    pd.DataFrame(index=["grid_" + str(i+1) for i in range(N_ROW * N_COL)]),
    df_grid, right_index=True, left_index=True, how="left"
).fillna(np.nan)

# extract section info
df_region = pd.DataFrame(
    np.array(df_shotest["region"]).reshape(N_ROW, N_COL).T.reshape(N_ROW * N_COL),
    index=["grid_" + str(i+1) for i in range(N_ROW * N_COL)], columns=["region"]
)

# marge
df_grid_region = pd.merge(
    df_grid, df_region,
    right_index=True, left_index=True, how="left"
)
df_grid_region = df_grid_region.dropna()

# add to obs
grid.obs = pd.merge(
    grid.obs, df_grid_region[["region"]],
    right_index=True, left_index=True, how="left"
)

# shaping
grid.obs["region_10"] = [str(i*10) for i in grid.obs["region"]]
grid.obs["region_10"] = ["("+str(int(float(i.split(", ")[0][1:])))+", "+str(int(float(i.split(", ")[-1][:-1])))+"]" if i != "nan" else np.nan for i in grid.obs["region_10"]]
# exclude because of small number
grid.obs["region_10"] = grid.obs["region_10"].replace(
    {"(-150, -120]": np.nan}
)
from scomv.preparation.choose_roi import extract_roi, contour_regions
# select ROI
roi = (2400, 3400, 2400, 3800)

subset_grid, filtered_shortest, xy_list = extract_roi(
    grid=grid,
    roi=roi,
    bin_size=10,
    region_col="region_10",
)
g_x_cont, g_y_cont, g_x_inside, g_y_inside = contour_regions(
    filtered_shortest, adata,
    min_x=0, max_x=4000, min_y=0, max_y=4000,
    show=True,
)
../../_images/3525bccf7d8144f2e710c1c108bc2bf6e18683f18619ca726ab34b0b421d1023.png
from scomv.preparation.scomv_calc_vector import compute_min_vectors_polar

outline_points = list(zip(g_x_cont, g_y_cont))
inside_points  = list(zip(g_x_inside, g_y_inside))

min_vector_df = compute_min_vectors_polar(
    xy_list=xy_list,
    outline_points=outline_points,
    inside_points=inside_points,
    invert_y=True,
    make_inside_negative=True,
)
# load cell_annotation file
file_path = "../tutorial_data/Cell_Barcode_Type_Matrices.xlsx"
xls = pd.ExcelFile(file_path)
cell_ann_df = pd.read_excel(file_path, sheet_name=xls.sheet_names[3])
print(cell_ann_df.head())

adata_obs = adata.obs
cell_ann_df.index = cell_ann_df.index + 1
adata_obs = adata_obs[["imagecol", "imagerow"]]
adata_obs.index = adata_obs.index.astype(int)


cell_df = pd.concat([adata_obs, cell_ann_df], axis=1)
cell_df = cell_df[["imagecol", "imagerow", "Cluster"]]
cell_df["Cluster"].unique()
#cell_df.to_csv("cell_annotation_df.csv")
   Barcode         Cluster
0        1          DCIS_2
1        2          DCIS_2
2        3       Unlabeled
3        4  Invasive_Tumor
4        5          DCIS_2
array(['DCIS_2', 'Unlabeled', 'Invasive_Tumor', 'Macrophages_1',
       'Stromal', 'DCIS_1', 'Myoepi_ACTA2+', 'CD8+_T_Cells',
       'Endothelial', 'Prolif_Invasive_Tumor', 'T_Cell_&_Tumor_Hybrid',
       'Mast_Cells', 'CD4+_T_Cells', 'B_Cells', 'Macrophages_2',
       'Stromal_&_T_Cell_Hybrid', 'Perivascular-Like', 'LAMP3+_DCs',
       'IRF7+_DCs', 'Myoepi_KRT15+'], dtype=object)
from scomv.cell_pipeline import CellPolarPipeline

# Initialize the pipeline with cell-level data and precomputed minimum-distance vectors
cell_pipe = CellPolarPipeline(
    cell_df=cell_df,
    min_vector_df=min_vector_df
)

# Run the pipeline for a specified ROI (xmin, xmax, ymin, ymax)
# Disable histogram plotting during the run
cell_out = cell_pipe.run(
    roi=(2400, 3400, 2400, 3800),
    plot_hist=False
)

# Distance matrix between cells based on polar-vector representations
dist = cell_pipe.dist_df

# Plot explained variance of PCoA components
cell_pipe.plot_explained_variance(n_components=8)

# Plot a heatmap of similarities (displayed as 1 - distance)
cell_pipe.heatmap(font_size=14, figsize=(8, 8))
../../_images/0224d61592048cd1327213628aecf7ddb411e318394dcce47f3628262e371f0f.png ../../_images/e91a9a71e5cc4b544b7b7a9c8b51d3b39b69b5e9541bbe2c993e8fd779a63c2b.png
<seaborn.matrix.ClusterGrid at 0x367e4e1d0>
from scomv.cell import compute_cluster_polar_distributions
_ = compute_cluster_polar_distributions(cell_out["cell_df_filtered"], min_vector_df)
../../_images/901301f473752ed823fb804709a3154153b855ca703092277ac0fa8c7399dd64.png ../../_images/7dd98388f1d5f30027f8bdaa3288b76c8866b8449f895b1627fa95f515911537.png ../../_images/72262bf9bc8969d5b05713dc9618ce1d3de92aac744b8e210da7373849089a37.png ../../_images/d8aaf228f2537f4b09b5e5763272851daace3135a8b39f97ee4aaf466e40ac25.png ../../_images/6544d1d6522c9cc6d6df5cdc33e74c41c5770461f989a2cfd2a8b3357e45f735.png ../../_images/078172408027cbb0d5862bd53b5cde2206a388d9a539188f2fce89386ff67d1a.png ../../_images/979617f51715b6d98cf3fbb4859f0225cfa736cf444cb1a066e295afd807d665.png ../../_images/4501acb8f8c11b5f24417b1ec55f8bebc0f5b3fb39edf065b65119d2ab846a7e.png ../../_images/ac2087e56557b1c15d7174c162f7852e8a622d916344f2bdd423342165376711.png ../../_images/9eb230c04bf188f447d460ad77f493726fec2e391b264f51c9b3caec3fd193f8.png ../../_images/ac4b061f33be1caaec9a797f3cf505603126d9225931957e4c24c3833e14d893.png
adata_2 = anndata.AnnData(X=np.zeros((len(cell_df), 0)))  # Dummy X
adata_2.obs = cell_df.copy()

# Store the coordinates used as the basis in adata.obsm
adata_2.obsm["spatial"] = cell_df[["imagecol", "imagerow"]].to_numpy()

# draw
sc.pl.embedding(
    adata_2,
    basis="spatial",
    color="Cluster",
    size=80,
    legend_loc=None,
    frameon=True,
    show=False,
)

ax = plt.gca()
ax.set_xlabel("X coordinate", fontsize=15)
ax.set_ylabel("Y coordinate", fontsize=15)
ax.tick_params(axis="both", labelsize=13)

# limit the range
ax.set_xlim(2400, 3400)
ax.set_ylim(2400, 3800)

# Align to the image coordinate system
ax.invert_yaxis()
ax.set_aspect("equal", adjustable="box")

legend = ax.legend(
    *ax.get_legend_handles_labels(),
    loc="center left",
    bbox_to_anchor=(1.02, 0.5),
    frameon=False,
    fontsize=12
)
plt.tight_layout()
plt.show()
/Users/nomura/miniconda3/envs/sc-test310/lib/python3.10/site-packages/anndata/_core/anndata.py:859: UserWarning:


AnnData expects .obs.index to contain strings, but got values like:
    [1, 2, 3, 4, 5]

    Inferred to be: integer
../../_images/0d2d5012e3440b06f759a9960d68bb4f22caf8170c761c7f1a8a855b3aeef5bd.png
sc.pl.embedding(
    adata_2,
    basis="spatial",
    color="Cluster",
    size=80,
    legend_loc="none",
    frameon=True,
    show=False,
)

ax = plt.gca()
ax.set_xlabel("X coordinate", fontsize=15)
ax.set_ylabel("Y coordinate", fontsize=15)
ax.tick_params(axis="both", labelsize=13)
ax.set_xlim(2400, 3400)
ax.set_ylim(2400, 3800)
ax.invert_yaxis()
ax.set_aspect("equal", adjustable="box")

# Retrieve category names and colors stored in adata
cats = adata_2.obs["Cluster"].astype("category").cat.categories
colors = adata_2.uns.get("Cluster_colors")

handles = [mpatches.Patch(color=c, label=str(cat)) for c, cat in zip(colors, cats)]
ax.legend(handles=handles, loc="center left", bbox_to_anchor=(1.02, 0.5), frameon=False, fontsize=12)

plt.subplots_adjust(right=0.80)
plt.tight_layout()
plt.show()
../../_images/044cb6c48039bb2100f52303ce9ac589c721eb90306f67268107497fdf565484.png
# List of cluster categories
clusters = adata_2.obs["Cluster"].astype("category").cat.categories

# Create a copy of adata and rename DCIS_2 → DCIS
adata_2_renamed = adata_2.copy()
adata_2_renamed.obs["Cluster"] = (
    adata_2_renamed.obs["Cluster"].replace({"DCIS_2": "DCIS"}).astype("category")
)

# Color settings: DCIS in yellow, others keep original colors
orig_cats = adata_2.obs["Cluster"].astype("category").cat.categories
orig_colors = adata_2.uns["Cluster_colors"]
color_dict = dict(zip(orig_cats, orig_colors))

cats = list(adata_2_renamed.obs["Cluster"].cat.categories)
colors = []
for c in cats:
    if c == "DCIS":
        colors.append("#FFD700")
    else:
        orig_name = "DCIS_2" if c == "DCIS" and "DCIS_2" in orig_cats else c
        colors.append(color_dict.get(orig_name, "gray"))

adata_2_renamed.uns["Cluster_colors"] = colors

# Plot "DCIS + each cluster" separately
for cluster in clusters:
    cluster_name = "DCIS" if cluster == "DCIS_2" else cluster

    plt.figure(figsize=(10, 10))
    sc.pl.spatial(
        adata_2_renamed[adata_2_renamed.obs["Cluster"].isin([cluster_name, "DCIS"])],
        img_key="hires",
        color="Cluster",
        size=1.5,
        spot_size=20,
        legend_loc="lower right",
        frameon=True,
        show=False,
    )

    ax = plt.gca()

    # Remove axis titles and labels
    ax.set_title("")
    ax.set_xlabel("")
    ax.set_ylabel("")
    ax.tick_params(axis="both", labelsize=11)

    # Manually construct legend for selected clusters
    handle_map = {cat: col for cat, col in zip(cats, adata_2_renamed.uns["Cluster_colors"])}
    show_labels = [cluster_name, "DCIS"]
    show_labels = list(dict.fromkeys(show_labels))  # Remove duplicates for DCIS plots
    handles = [
        mpatches.Patch(color=handle_map[label], label=label)
        for label in show_labels
    ]
    ax.legend(handles=handles, loc="lower right", frameon=True, fontsize=12)

    ax.set_axis_on()

    # Set ROI limits
    ax.set_xlim(2400, 3400)
    # ax.set_xticks(range(2400, 3401, 200))
    ax.set_ylim(2400, 3800)
    # ax.set_yticks(range(2400, 3801, 200))

    # Align to image coordinate system
    ax.invert_yaxis()
    ax.set_aspect("equal", adjustable="box")

    # Save figure (optional)
    # plt.savefig(f"{root}/cell_location_fig/{cluster_name}_no_tick.png", dpi=300)

    plt.show()
    print(f"Figure: {cluster_name} + DCIS")
/Users/nomura/miniconda3/envs/sc-test310/lib/python3.10/site-packages/anndata/_core/anndata.py:183: ImplicitModificationWarning:

Transforming to str index.

/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:7: FutureWarning:

The behavior of Series.replace (and DataFrame.replace) with CategoricalDtype is deprecated. In a future version, replace will only be used for cases that preserve the categories. To change the categories, use ser.cat.rename_categories instead.

/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/cb49a91e766558e830b375f685699ba1b5bd50e473ccfc7f5d6c00039ddb7dfd.png
Figure: B_Cells + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/ada8f2c6737f32ef4f2ad75ba60dcf87af6c871df2bf4d19d1f3156c69de334e.png
Figure: CD4+_T_Cells + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/cde9c5483f58822fbfc664148969e4da0fe336ff05eb9d6522a8e42899f1e19b.png
Figure: CD8+_T_Cells + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/2fc2328a4e1f64e280fb92e7e210360cf4a069629165861cb3ca3c49603e61e3.png
Figure: DCIS_1 + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/cf1949c28876e2d0806ef8484598c85f3b01da03fa36b317b3cabe310c8d8832.png
Figure: DCIS + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/32d68b735e48d9cf53846051e8bb5f58e00bfe16cc7fe11ba8097c7dd2d177c9.png
Figure: Endothelial + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/f5e8eea9a0647305cd3ff5a73cb917b112c431937991781802330b565467d9f8.png
Figure: IRF7+_DCs + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/09264a42f6b5681ec8f1c06dd3105ec31d07d3ec2b25ba3477504a182f7f0f65.png
Figure: Invasive_Tumor + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/7c97b92fba34f78367bf2915a12405f925fbbcbc164ade0f5a42d75a45174032.png
Figure: LAMP3+_DCs + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/1fb48a43affef247588dbdb496b7cadad4d7514cddaa066fc06cf343530725e0.png
Figure: Macrophages_1 + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/83ab5ac6999d15f0dd84ccc41546197eb804169e6e71ad74b8615b147db1bc30.png
Figure: Macrophages_2 + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/59f31d91cb874afbe06079e333de0d8c6119eb0eb3b7f809797d1b6cf7d8d596.png
Figure: Mast_Cells + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/db90fec2bb9acaaab03ec53d29c73bce0c4fe8e45e66460155401b8c01bd0c00.png
Figure: Myoepi_ACTA2+ + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/8809b20f3aaf8b7a572db77242d1dca45d11c14d99438566e4570020d9104c93.png
Figure: Myoepi_KRT15+ + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/c9478132c0b0bd7c73bbe9bc4fc540c3e3c6d9f8a74ecb14ba8cd3a588cd6b83.png
Figure: Perivascular-Like + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/db56403158c8ea9d9b23d16edc05f64ebdcc20404a0983dcc50e5d49c95b9524.png
Figure: Prolif_Invasive_Tumor + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/c995746c1a2cc7039e12b9473ca3720525951123290f83a54b05ae8f623e345f.png
Figure: Stromal + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/afa494a63a11832a0b196244e697ca9cdc8c625a50fb8aa057b5707a26e403e2.png
Figure: Stromal_&_T_Cell_Hybrid + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/53617eb59e9ed3e625c4990e6c48f3b2974222485d21d4b1deef4a97d8d8c3e9.png
Figure: T_Cell_&_Tumor_Hybrid + DCIS
/var/folders/h5/02yhm93d3kn1__fczqjdr9cw0000gp/T/ipykernel_69162/3277719802.py:31: FutureWarning:

Use `squidpy.pl.spatial_scatter` instead.
<Figure size 1000x1000 with 0 Axes>
../../_images/b2efd28d4b2931ab871069e0c4535183b4a5a4a1366446e414a471e12a678401.png
Figure: Unlabeled + DCIS