This release contains changes in cell-cell interaction (CCI) mainly improvements in runtime and memory usage and requires code to be updated.
- Memory usage is reduced through chunking (~256MB) in
st.cci.runscoring and permutation testing. On a 5,000,000 bin synthetic Visium HD sample with connectomeDB2025, n_pairs=1000, runs take ~24GB in ~10 minutes. - SpatialData support added with a new
st.iopackage. Supporting:atera,xenium,visium_hdandvisium. Start of spatial data native plotting withst.pl.sdata_plotand added AnnData'sst.pp.highly_variable_genes. - New datasets
st.datasets.visium_hd_sgeandatera_sge. All four dataset functions now return SpatialData objects;visium_sgereturned AnnData andxenium_sgeonly downloaded the files. - Upgraded ligand-receptor databases to connectomeDB2025 (human and mouse).
- Ligand-receptor pairs are an
LRPairsobject instead of an array of 'L_R' strings. It tracks the species and where each pair came from. Pairs can be filtered and combined (lrs.filter(...),lrs1 | lrs2).st.tl.cci.runtakes onlyLRPairs; an array of 'L_R' names raisesTypeError. Wrap strings withst.tl.cci.LRPairs.from_names(names, species="human").st.tl.cci.lr_pairs(database, species)loads a database shipped with stLearn:"connectomeDB2025"(default; human or mouse) or"connectomeDB2020"(human).st.tl.cci.read_lr_pairs(path, species=...)reads your own csv/tsv of ligand and receptor columns.st.tl.cci.load_lrsis deprecated and all APIs now uselr_pairs, orlr_pairs(...).names()for the old array. Note thatlr_pairs()defaults to connectomeDB2025, whereload_lrs()defaults to connectomeDB2020.- Previous databases names
"connectomeDB2020_lit"and"connectomeDB2020_put"are removed."connectomeDB2020"is the human only, literature pairs and the putative pairs are no longer shipped. st.add.lris removed; useread_lr_pairsorLRPairs.from_names.- The LR table from
runstores each pair's source invar["source"]and the species inuns["lr_species"], whichrun_lr_gouses as its default species.
- Spatial trajectory and other APIs use cluster label strings
(
cluster="6"). - AnnData backwards compatibility available through
st.io.attach_spatialfor Visium/Visium HD andst.io.attach_spatial_sdatafor Xenium/Atera. - CCI results are now a LR table (AnnData) returned by
st.tl.cci.run. A spots x LR pairs with summaries invarand scores and p-values are in sparselayers. Downstream functions and plots now takelr_results. - Support for microns through
microns_per_pixel,st.utils.microns_to_pixels,pixels_to_micronsandcreate_grid(bin_um=). - SME computes weights only between nearby spots and data is kept sparse where possible.
st.pp.extract_featuresupports ConvNeXt and takesweights=.- Upgrade libraries: pillow>=13.0.0,<14.0, numba>=0.64.0, scikit-image>=0.25.0, torch>=2.5.0, matplotlib>=3.11,<4.0.
API and Bug Fixes:
- Fixed double application of scaling, adding instructions and warning for
image alignment in
st.io.create_stlearnBug #303. - A pair listed twice is now tested once - fixed Bug #305.
- Incorrect labelling in CCI Plot - rows labelled "Senders", columns labelled "Receivers" - should be the other way around Bugs #309, #363.
- SME failed with "Input X contains NaN" when a spot had no
array_row/array_col- these are now left out of the spot spacing fit - fixed Bug #310. st.tl.cci.run(use_label=...)never applied cell heterogeneity weighting: it read the cell-type data from the wrong key, found nothing, and weighted every spot 1, so results were identical with and withoutuse_label. It now weights by heterogeneity from cell-type proportions inuns[use_label]or per-cell labels inobs[use_label], and takescell_prop_cutoff. CCI scores and significance change for any run that useduse_label.st.tl.cci.run_cci: p-values from permutation are now(k+1)/(N+1)and can no longer be 0, cutoff is nowp < p_cutoff, and each permutation thread is seeded throughrandom_state.spot_mixturesmatches cell types by exact name.- When
min_expr > 0n_spotsin the LR summary counted spots with a score abovemin_expr, while themin_spotsfilter counted spots with a score above 0, so the reported count was not the one the filter used. Both now use score > 0. st.tl.cci.griddropped cells lying exactly on the inner edge of the last row or column of the grid, and on the outer edges of the corner square.st.pl.lr_plotstatistic names were changed fromp_val,p_adjand-log10(p_adj)top_vals,p_adjsandneg_log10_p_adjs. It always drewlr_sig_scoreswhateveruse_labelasked for, so a plot labelledp_adjsorneg_log10_p_adjsshowed the masked score instead.st.pl.lr_plotandst.pl.ccinet_plotalso draw on afigoraxyou passed in rather than opening a new figure, so they can go in subplots.- Images in
uns["spatial"]are now uint8 (0-255), not floats in [0, 1]. st.pp.extract_featuretiles were fed as floats between 0-255 instead of 0-1. Tiles are now read as uint8, soX_tile_featureandX_morphologychange.st.concatenate_spatial_adata: the x and y offsets added toobsm["spatial"]for each tile were swapped, so spots on any tile off the diagonal landed on the wrong tile. Tiles also keep their aspect ratio instead of being stretched tofixed_size, each sample is scaled by its own scale factor rather than the first sample's, andfixed_sizeis (height, width) like a NumPy shape.st.io.read_merfishworks again with new notebook. Defaultsspot_diameter_fullresto 10 (it was 50).st.io.read_10xreads 16-bit / signed PNGs and reports missing images clearly.st.add.labels/st.add.add_loupe_clustersmatch by barcode.st.add.positionsreads Space Ranger 2.0+ files.st.add.parsingassigned spots the wrong coordinates (they were interleaved from the spots inobs), so every plot and anything usingobsm["spatial"]was wrong. Each spot now gets its own position.- SME fits each axis separately when finding neighbours.
- Spatial trajectory:
st.spatial.trajectory.pseudotimeorients by median pseudotime (paths may differ),shortest_path_spatial_pagareturns labels, plus fixes tolocal_level,weight_optimizing_local,de_transition_plotand the trajectory plots. st.pl.qc_plotno longer makes a dense copy.- Readers were moved to
st.io:st.read_10x,st.read_xenium,st.read_old_st,st.read_slide_seq,st.read_merfish,st.read_seq_fishandst.create_stlearn. st.tl.cci.gridvectorised and no longer takesn_cpus.obsm["spatial"]is in full-resolution pixels (was image pixels), matching the rest of stLearn (used byst.tl.cci.grid).- SME outputs are sparse when
Xis sparse; no weight matrices inuns. - Removed:
extract_feature(cnn_base="xception"),deconvolution_plot(data_alpha=),local_plot(cluster=),Spatial(basis=). - New defaults:
pl.trajectory.pseudotime_plot(node_size=60)(area);pl.trajectory.check_trajectory(size_spatial=7, img_key=None). st.spatial.trajectory.pseudotimeno longer takesn_neighbors,use_reporrun_knn- these must be run prior and will throw an exception if there's no neighbourhood graph.
- Improved speed of random spot generation used in permutation testing.
API and Bug Fixes: * Fixed up docstring and types for various CCI methods. * Fixes for issues #350 and #300 with incorrect types. * Upgrade libraries: pillow>=12.0.0,<13.0
- Removed tensorflow and keras and replaced with torch and torchvision.
- The CCI implementation removed string comparisons for spot-pair edges and replaced it with one set of two packed 32 bit integers. Removed deduplication pass (m^2) with a hash lookup (O(n)).
- Upgrade libraries: numpy >=2.4.0, scanpy >= 1.12.0, scipy >= 1.17.0, added spatialdata, shapely, geopandas.
API and Bug Fixes: * Added row and polygon annotations. * Fixed exception handling to catch previous exceptions when rethrown.
- Removed interactive stLearn/embedded web application.
- Removed louvain clustering - replaced with leiden.
API and Bug Fixes: * Fix import on MutableVertexPartition to use leidenalg.VertexPartition. * Switch default flavour in leiden to use igraph (and its required parameters). * Renamed methods and classes to follow lowercase standard.
- Added support for Python 3.11 and 3.12.
- Upgraded scanpy to 1.11 - clustering will be different.
- Added more CCI tests.
API and Bug Fixes:
* Fixed copy-paste error in leiden.py file.
- Add Leiden clustering wrapper.
- Fix documentation, refactor code in spatial.SME.
- Support Python 3.10.x
- Added quality checks black, ruff and mypy and fixed appropriate source code.
- Copy parameters now work with the same semantics as scanpy.
- Library upgrades for leidenalg, louvain, numba, numpy, scanpy, and tensorflow.
- datasets.xenium_sge - loads Xenium data (and caches it) similar to scanpy.visium_sge.
API and Bug Fixes:
- Xenium TIFF and cell positions are now aligned.
- Consistent with type annotations - mainly missing None annotations.
- pl.cluster_plot - Does not keep colours from previous runs when clustering.
- pl.trajectory.pseudotime_plot - Fix typing of cluster values in .uns["split_node"].
- Removed datasets.example_bcba - Replaced with wrapper for scanpy.visium_sge.
- Moved spatials directory to spatial, cleaned up pl and tl packages.