API Reference

Top-level

Top-level package for SpatialCompassV.

class scomv.CellPolarPipeline(cell_df: DataFrame, min_vector_df: DataFrame, cluster_col: str = 'Cluster', x_col: int = 0, y_col: int = 1, bin_size: int = 10, coord_col: str = 'coord_tuple', unlabeled_name: str = 'Unlabeled', min_cells: int = 30, bin_size_um: int = 10, radius_bins: ndarray | None = None, angle_bins_deg: ndarray | None = None, last_roi: Tuple[float, float, float, float] | None = None, cell_df_filtered: DataFrame | None = None, selected_clusters: List[str] | None = None, polar_counts_list: List[ndarray] | None = None, counts_by_cluster: Dict[str, ndarray] | None = None, dist_df: DataFrame | None = None, pcoa_res: Any | None = None, coords: DataFrame | None = None, explained: Series | None = None)[source]

Bases: object

A pipeline that takes a cell-level table (x, y, Cluster) and a min_vector_df (indexed by grid coordinates), then performs: - cluster-wise polar distributions - inter-cluster distance computation - PCoA / heatmap visualization

angle_bins_deg: ndarray | None = None
annotate_cells(roi: Tuple[float, float, float, float], *, bin_size: int | None = None, coord_col: str | None = None) DataFrame[source]

Filter cells within the ROI and add coord_tuple as (floor(x/bin), floor(y/bin)).

bin_size: int = 10
bin_size_um: int = 10
build_distance(*, make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
cell_df: DataFrame
cell_df_filtered: DataFrame | None = None
cell_polar_maps(*, cell_df_filtered: DataFrame | None = None, plot: bool = True, clim_ratio: float = 0.5, cmap: str = 'viridis', xlim: Tuple[float, float] = (-150, 300), ylim: Tuple[float, float] = (-180, 180)) Tuple[List[ndarray], List[str], Dict[str, ndarray]][source]
static cell_similarity_matrix(polar_counts_list: List[ndarray], labels: Sequence[str], make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
cluster_col: str = 'Cluster'
coord_col: str = 'coord_tuple'
coords: DataFrame | None = None
counts_by_cluster: Dict[str, ndarray] | None = None
dist_df: DataFrame | None = None
explained: Series | None = None
heatmap(dist_df: DataFrame | None = None, method: str = 'ward', metric: str = 'euclidean', cmap: str = 'viridis', figsize: Tuple[int, int] = (10, 10), font_size: int = 18, rotation: int = 90, show_similarity: bool = True)[source]
last_roi: Tuple[float, float, float, float] | None = None
min_cells: int = 30
min_vector_df: DataFrame
pcoa_res: Any = None
plot_explained_variance(n_components: int = 10, figsize: Tuple[int, int] = (8, 4), title: str = 'PCoA Explained Variance', ylabel: str = 'Proportion Explained', xlabel: str = 'PCoA Axis', show_values: bool = True)[source]
polar_counts_list: List[ndarray] | None = None
radius_bins: ndarray | None = None
run(roi: Tuple[float, float, float, float], *, plot_hist: bool = False, clim_ratio: float = 0.5) Dict[str, Any][source]
run_pcoa(dist_df: DataFrame | None = None)[source]
selected_clusters: List[str] | None = None
unlabeled_name: str = 'Unlabeled'
x_col: int = 0
y_col: int = 1
class scomv.SCOMVPipeline(adata: 'Any', grid: 'Any', bin_size: 'int' = 10, region_col: 'str' = 'region_10', subsample_fraction: 'float' = 0.5, min_gene_percentile: 'float' = 30, max_gene_percentile: 'float' = 95, require_moran_nonneg: 'bool' = True, contour_bounds: 'Tuple[float, float, float, float]' = (0, 10000, 0, 10000), invert_y: 'bool' = True, make_inside_negative: 'bool' = True, radius_bins: 'Optional[np.ndarray]' = None, angle_bins_deg: 'Optional[np.ndarray]' = None, last_roi: 'Optional[Tuple[float, float, float, float]]' = None, subset_grid: 'Any' = None, filtered_shortest: 'Any' = None, xy_list: 'Any' = None, outline_points: 'Optional[List[Tuple[float, float]]]' = None, inside_points: 'Optional[List[Tuple[float, float]]]' = None, min_vector_df: 'Optional[pd.DataFrame]' = None, moran_df: 'Optional[pd.DataFrame]' = None, gene_lens: 'Optional[np.ndarray]' = None, p_low: 'Optional[int]' = None, p_high: 'Optional[int]' = None, selected_genes: 'Optional[List[str]]' = None, polar_counts_list: 'Optional[List[np.ndarray]]' = None, dist_df: 'Optional[pd.DataFrame]' = None, pcoa_res: 'Any' = None, coords: 'Optional[pd.DataFrame]' = None, explained: 'Optional[pd.Series]' = None)[source]

Bases: object

adata: Any
angle_bins_deg: ndarray | None = None
bin_size: int = 10
build_polar_distributions_for_genes(adata_grid, min_vector_df: DataFrame, moran_df: DataFrame | None = None, min_gene_count: int = 0, require_moran_nonneg: bool | None = None, bin_size_um: int | None = None, make_plots: bool = False, clim_ratio: float = 0.15) Tuple[List[ndarray], List[str]][source]
compute_moran_df(roi: Tuple[float, float, float, float], subsample_fraction: float | None = None, delaunay: bool = True, n_perms: int = 100, n_jobs: int = 1, plot_cdf: bool = False) DataFrame[source]
contour_bounds: Tuple[float, float, float, float] = (0, 10000, 0, 10000)
coords: DataFrame | None = None
dist_df: DataFrame | None = None
explained: Series | None = None
filtered_shortest: Any = None
gene_lens: ndarray | None = None
static gene_total_counts_int(adata) ndarray[source]
grid: Any
inside_points: List[Tuple[float, float]] | None = None
invert_y: bool = True
last_roi: Tuple[float, float, float, float] | None = None
make_inside_negative: bool = True
max_gene_percentile: float = 95
min_gene_percentile: float = 30
min_vector_df: DataFrame | None = None
static minas_similarity_matrix(polar_counts_list: List[ndarray], labels: List[str], make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
moran_df: DataFrame | None = None
outline_points: List[Tuple[float, float]] | None = None
p_high: int | None = None
p_low: int | None = None
pcoa_res: Any = None
static plot_pcoa_plotly(coords: DataFrame, labels: List[str], width: int = 720, height: int = 540, margin: float = 0.05)[source]
polar_counts_list: List[ndarray] | None = None
radius_bins: ndarray | None = None
region_col: str = 'region_10'
require_moran_nonneg: bool = True
run(roi: Tuple[float, float, float, float], *, subset_grid=None, filtered_shortest=None, xy_list=None, outline_points=None, inside_points=None, bin_size: int | None = None, region_col: str | None = None, subsample_fraction: float | None = None, min_gene_percentile: float | None = None, max_gene_percentile: float | None = None, require_moran_nonneg: bool | None = None, contour_bounds: Tuple[float, float, float, float] | None = None, invert_y: bool | None = None, make_inside_negative: bool | None = None, make_plots: bool = False) Dict[str, Any][source]
static run_pcoa_from_distance_df(dist_df: DataFrame)[source]
selected_genes: List[str] | None = None
subsample_fraction: float = 0.5
static subset_by_roi(adata, roi: Tuple[float, float, float, float])[source]
subset_grid: Any = None
xy_list: Any = None
class scomv.Spatial_DEG(n_components: int | None = None, standardize: bool = True, random_state: int | None = None)[source]

Bases: object

Standardize -> PCA -> plots & utilities.

Notes

  • X: shape (n_samples, n_features)

  • feature_names: length n_features (gene/cluster names etc.)

property components_: ndarray
property cumulative_variance_ratio_: ndarray
property explained_variance_ratio_: ndarray
fit(X: ndarray | DataFrame, feature_names: Sequence[str] | None = None)[source]
fit_umap_on_loadings(n_components: int = 2, n_neighbors: int = 10, min_dist: float = 0.1, metric: str = 'euclidean', random_state: int = 42)[source]

Fit UMAP on PCA loadings (features = PCs, rows = genes/features).

Returns:

umap_coords – columns = [“UMAP1”, “UMAP2”] (or more if n_components>2), index = feature_names

Return type:

pd.DataFrame

get_loadings_df(pcs: Sequence[int] | None = None) DataFrame[source]
get_top_genes_signed(pcs: Sequence[int] = (0, 1, 2), top_pos: int = 10, top_neg: int = 10, sort_by: str = 'value') DataFrame[source]
property loadings_: ndarray

shape (n_features, n_components) = components_.T

Type:

loadings (a.k.a contributions in your code)

plot_explained_variance_bar(max_pc: int = 10, figsize=(7, 4), color='steelblue', show_values: bool = True)[source]

Bar plot of explained variance ratio for each PC (non-cumulative).

Parameters:
  • max_pc (int) – Number of PCs to display (e.g. 10)

  • show_values (bool) – Annotate bars with values

plot_loading_violin(pcs: Sequence[int] = (0, 1, 2), figsize: Tuple[int, int] = (5, 6), cut: float = 0)[source]

Violin plot of loadings for selected PCs.

plot_signed_top_contributions(pc: int = 0, top_pos: int = 10, top_neg: int = 10, figsize: Tuple[int, int] = (6, 12), pos_color: str = '#C0392B', neg_color: str = '#5DADE2', xlabel: str | None = None, title: str | None = None, ytick_fontsize: int = 25, xtick_fontsize: int = 18)[source]

Signed horizontal bar plot: top positive and top negative (by abs) contributors.

plot_signed_top_contributions_multi(pcs: Sequence[int] = (0, 1, 2), top_pos: int = 10, top_neg: int = 10, figsize: Tuple[int, int] = (6, 12))[source]

Convenience: plot for PC1, PC2, PC3… in a loop.

plot_umap_loadings_interactive(umap_df: DataFrame | None = None, title: str = 'UMAP of PCA Loadings (Gene Embedding)', width: int = 650, height: int = 650, marker_size: int = 7)[source]

Interactive scatter (hover shows gene/feature name) using Plotly.

scomv.dendrogram2newick(node: ClusterNode, parent_dist: float, leaf_names: List[str], newick: str = '') str[source]

Convert scipy dendrogram tree to newick format tree

Parameters:
  • node (ClusterNode) – Tree node

  • parent_dist (float) – Parent distance

  • leaf_names (List[str]) – Leaf names

  • newick (str) – newick format string (Used in recursion)

Returns:

Newick format tree

Return type:

str

scomv.plot_3d(adata, genes: str | Sequence[str], anchor_gene: str = 'CDH1', bin_size: int = 10, x_range: Tuple[float, float] | None = None, y_range: Tuple[float, float] | None = None, height_scale: float = 5.0, anchor_scale: float = 1.0, threshold: float = 4.0, sigma: float = 1.0, reverse_x: bool = True, colors: dict | None = None, agg: str = 'mean', interpolate_missing: bool = True, smooth_mode: str = 'reflect')[source]

Modules

class scomv.cell_pipeline.CellPolarPipeline(cell_df: DataFrame, min_vector_df: DataFrame, cluster_col: str = 'Cluster', x_col: int = 0, y_col: int = 1, bin_size: int = 10, coord_col: str = 'coord_tuple', unlabeled_name: str = 'Unlabeled', min_cells: int = 30, bin_size_um: int = 10, radius_bins: ndarray | None = None, angle_bins_deg: ndarray | None = None, last_roi: Tuple[float, float, float, float] | None = None, cell_df_filtered: DataFrame | None = None, selected_clusters: List[str] | None = None, polar_counts_list: List[ndarray] | None = None, counts_by_cluster: Dict[str, ndarray] | None = None, dist_df: DataFrame | None = None, pcoa_res: Any | None = None, coords: DataFrame | None = None, explained: Series | None = None)[source]

Bases: object

A pipeline that takes a cell-level table (x, y, Cluster) and a min_vector_df (indexed by grid coordinates), then performs: - cluster-wise polar distributions - inter-cluster distance computation - PCoA / heatmap visualization

angle_bins_deg: ndarray | None = None
annotate_cells(roi: Tuple[float, float, float, float], *, bin_size: int | None = None, coord_col: str | None = None) DataFrame[source]

Filter cells within the ROI and add coord_tuple as (floor(x/bin), floor(y/bin)).

bin_size: int = 10
bin_size_um: int = 10
build_distance(*, make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
cell_df: DataFrame
cell_df_filtered: DataFrame | None = None
cell_polar_maps(*, cell_df_filtered: DataFrame | None = None, plot: bool = True, clim_ratio: float = 0.5, cmap: str = 'viridis', xlim: Tuple[float, float] = (-150, 300), ylim: Tuple[float, float] = (-180, 180)) Tuple[List[ndarray], List[str], Dict[str, ndarray]][source]
static cell_similarity_matrix(polar_counts_list: List[ndarray], labels: Sequence[str], make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
cluster_col: str = 'Cluster'
coord_col: str = 'coord_tuple'
coords: DataFrame | None = None
counts_by_cluster: Dict[str, ndarray] | None = None
dist_df: DataFrame | None = None
explained: Series | None = None
heatmap(dist_df: DataFrame | None = None, method: str = 'ward', metric: str = 'euclidean', cmap: str = 'viridis', figsize: Tuple[int, int] = (10, 10), font_size: int = 18, rotation: int = 90, show_similarity: bool = True)[source]
last_roi: Tuple[float, float, float, float] | None = None
min_cells: int = 30
min_vector_df: DataFrame
pcoa_res: Any = None
plot_explained_variance(n_components: int = 10, figsize: Tuple[int, int] = (8, 4), title: str = 'PCoA Explained Variance', ylabel: str = 'Proportion Explained', xlabel: str = 'PCoA Axis', show_values: bool = True)[source]
polar_counts_list: List[ndarray] | None = None
radius_bins: ndarray | None = None
run(roi: Tuple[float, float, float, float], *, plot_hist: bool = False, clim_ratio: float = 0.5) Dict[str, Any][source]
run_pcoa(dist_df: DataFrame | None = None)[source]
selected_clusters: List[str] | None = None
unlabeled_name: str = 'Unlabeled'
x_col: int = 0
y_col: int = 1
class scomv.gene_pipeline.SCOMVPipeline(adata: 'Any', grid: 'Any', bin_size: 'int' = 10, region_col: 'str' = 'region_10', subsample_fraction: 'float' = 0.5, min_gene_percentile: 'float' = 30, max_gene_percentile: 'float' = 95, require_moran_nonneg: 'bool' = True, contour_bounds: 'Tuple[float, float, float, float]' = (0, 10000, 0, 10000), invert_y: 'bool' = True, make_inside_negative: 'bool' = True, radius_bins: 'Optional[np.ndarray]' = None, angle_bins_deg: 'Optional[np.ndarray]' = None, last_roi: 'Optional[Tuple[float, float, float, float]]' = None, subset_grid: 'Any' = None, filtered_shortest: 'Any' = None, xy_list: 'Any' = None, outline_points: 'Optional[List[Tuple[float, float]]]' = None, inside_points: 'Optional[List[Tuple[float, float]]]' = None, min_vector_df: 'Optional[pd.DataFrame]' = None, moran_df: 'Optional[pd.DataFrame]' = None, gene_lens: 'Optional[np.ndarray]' = None, p_low: 'Optional[int]' = None, p_high: 'Optional[int]' = None, selected_genes: 'Optional[List[str]]' = None, polar_counts_list: 'Optional[List[np.ndarray]]' = None, dist_df: 'Optional[pd.DataFrame]' = None, pcoa_res: 'Any' = None, coords: 'Optional[pd.DataFrame]' = None, explained: 'Optional[pd.Series]' = None)[source]

Bases: object

adata: Any
angle_bins_deg: ndarray | None = None
bin_size: int = 10
build_polar_distributions_for_genes(adata_grid, min_vector_df: DataFrame, moran_df: DataFrame | None = None, min_gene_count: int = 0, require_moran_nonneg: bool | None = None, bin_size_um: int | None = None, make_plots: bool = False, clim_ratio: float = 0.15) Tuple[List[ndarray], List[str]][source]
compute_moran_df(roi: Tuple[float, float, float, float], subsample_fraction: float | None = None, delaunay: bool = True, n_perms: int = 100, n_jobs: int = 1, plot_cdf: bool = False) DataFrame[source]
contour_bounds: Tuple[float, float, float, float] = (0, 10000, 0, 10000)
coords: DataFrame | None = None
dist_df: DataFrame | None = None
explained: Series | None = None
filtered_shortest: Any = None
gene_lens: ndarray | None = None
static gene_total_counts_int(adata) ndarray[source]
grid: Any
inside_points: List[Tuple[float, float]] | None = None
invert_y: bool = True
last_roi: Tuple[float, float, float, float] | None = None
make_inside_negative: bool = True
max_gene_percentile: float = 95
min_gene_percentile: float = 30
min_vector_df: DataFrame | None = None
static minas_similarity_matrix(polar_counts_list: List[ndarray], labels: List[str], make_distance: bool = True, fill_diagonal_zero: bool = True) DataFrame[source]
moran_df: DataFrame | None = None
outline_points: List[Tuple[float, float]] | None = None
p_high: int | None = None
p_low: int | None = None
pcoa_res: Any = None
static plot_pcoa_plotly(coords: DataFrame, labels: List[str], width: int = 720, height: int = 540, margin: float = 0.05)[source]
polar_counts_list: List[ndarray] | None = None
radius_bins: ndarray | None = None
region_col: str = 'region_10'
require_moran_nonneg: bool = True
run(roi: Tuple[float, float, float, float], *, subset_grid=None, filtered_shortest=None, xy_list=None, outline_points=None, inside_points=None, bin_size: int | None = None, region_col: str | None = None, subsample_fraction: float | None = None, min_gene_percentile: float | None = None, max_gene_percentile: float | None = None, require_moran_nonneg: bool | None = None, contour_bounds: Tuple[float, float, float, float] | None = None, invert_y: bool | None = None, make_inside_negative: bool | None = None, make_plots: bool = False) Dict[str, Any][source]
static run_pcoa_from_distance_df(dist_df: DataFrame)[source]
selected_genes: List[str] | None = None
subsample_fraction: float = 0.5
static subset_by_roi(adata, roi: Tuple[float, float, float, float])[source]
subset_grid: Any = None
xy_list: Any = None
class scomv.spatial_deg.Spatial_DEG(n_components: int | None = None, standardize: bool = True, random_state: int | None = None)[source]

Bases: object

Standardize -> PCA -> plots & utilities.

Notes

  • X: shape (n_samples, n_features)

  • feature_names: length n_features (gene/cluster names etc.)

property components_: ndarray
property cumulative_variance_ratio_: ndarray
property explained_variance_ratio_: ndarray
fit(X: ndarray | DataFrame, feature_names: Sequence[str] | None = None)[source]
fit_umap_on_loadings(n_components: int = 2, n_neighbors: int = 10, min_dist: float = 0.1, metric: str = 'euclidean', random_state: int = 42)[source]

Fit UMAP on PCA loadings (features = PCs, rows = genes/features).

Returns:

umap_coords – columns = [“UMAP1”, “UMAP2”] (or more if n_components>2), index = feature_names

Return type:

pd.DataFrame

get_loadings_df(pcs: Sequence[int] | None = None) DataFrame[source]
get_top_genes_signed(pcs: Sequence[int] = (0, 1, 2), top_pos: int = 10, top_neg: int = 10, sort_by: str = 'value') DataFrame[source]
property loadings_: ndarray

shape (n_features, n_components) = components_.T

Type:

loadings (a.k.a contributions in your code)

plot_explained_variance_bar(max_pc: int = 10, figsize=(7, 4), color='steelblue', show_values: bool = True)[source]

Bar plot of explained variance ratio for each PC (non-cumulative).

Parameters:
  • max_pc (int) – Number of PCs to display (e.g. 10)

  • show_values (bool) – Annotate bars with values

plot_loading_violin(pcs: Sequence[int] = (0, 1, 2), figsize: Tuple[int, int] = (5, 6), cut: float = 0)[source]

Violin plot of loadings for selected PCs.

plot_signed_top_contributions(pc: int = 0, top_pos: int = 10, top_neg: int = 10, figsize: Tuple[int, int] = (6, 12), pos_color: str = '#C0392B', neg_color: str = '#5DADE2', xlabel: str | None = None, title: str | None = None, ytick_fontsize: int = 25, xtick_fontsize: int = 18)[source]

Signed horizontal bar plot: top positive and top negative (by abs) contributors.

plot_signed_top_contributions_multi(pcs: Sequence[int] = (0, 1, 2), top_pos: int = 10, top_neg: int = 10, figsize: Tuple[int, int] = (6, 12))[source]

Convenience: plot for PC1, PC2, PC3… in a loop.

plot_umap_loadings_interactive(umap_df: DataFrame | None = None, title: str = 'UMAP of PCA Loadings (Gene Embedding)', width: int = 650, height: int = 650, marker_size: int = 7)[source]

Interactive scatter (hover shows gene/feature name) using Plotly.