Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,18 @@ Initial feature-complete Python port of the [SelectSim R package](https://github
* This round of work was developed with the assistance of Claude Code
(Anthropic), directed and verified by Arvind Iyer throughout; see
`git log` for detailed commit history.

# SelectSim (Python) 0.3.1

* **Performance**: `import selectsim` dropped from ~1.5s to ~0.6s. The
top-level package eagerly imported `selectsim.plotting`, which pulls in
`matplotlib` and `scipy` (used nowhere outside `plotting.py`), even for
callers who only ever call `selectX()` and never plot anything.
Plotting functions (`obs_exp_scatter`, `ridge_plot_ed`, `oncoprint`,
etc.) are now resolved lazily on first access (PEP 562 module
`__getattr__`) instead -- same `ss.<name>` usage, just deferred. On the
bundled LUAD benchmark this cut whole-process wall time by ~23% and
peak memory by ~21%.
* **Removed**: the `seaborn` dependency. It was listed in
`pyproject.toml` and mentioned in a couple of docstrings, but never
actually imported or used anywhere in the codebase.
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
project = 'SelectSim'
copyright = '2026, Arvind Iyer, Marco Mina, Miljan Petrovic, Giovanni Ciriello'
author = 'Arvind Iyer, Marco Mina, Miljan Petrovic, Giovanni Ciriello'
release = '0.3.0'
release = '0.3.1'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
114 changes: 56 additions & 58 deletions docs/source/tutorials/introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
"id": "d465b22a",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:47.821334Z",
"iopub.status.busy": "2026-07-14T19:10:47.820804Z",
"iopub.status.idle": "2026-07-14T19:10:49.335540Z",
"shell.execute_reply": "2026-07-14T19:10:49.334213Z"
"iopub.execute_input": "2026-07-14T21:19:47.586776Z",
"iopub.status.busy": "2026-07-14T21:19:47.586296Z",
"iopub.status.idle": "2026-07-14T21:19:48.517073Z",
"shell.execute_reply": "2026-07-14T21:19:48.515872Z"
}
},
"outputs": [],
Expand Down Expand Up @@ -88,10 +88,10 @@
"id": "b116ad1e",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:49.339285Z",
"iopub.status.busy": "2026-07-14T19:10:49.338828Z",
"iopub.status.idle": "2026-07-14T19:10:49.449444Z",
"shell.execute_reply": "2026-07-14T19:10:49.448430Z"
"iopub.execute_input": "2026-07-14T21:19:48.521338Z",
"iopub.status.busy": "2026-07-14T21:19:48.520743Z",
"iopub.status.idle": "2026-07-14T21:19:48.624345Z",
"shell.execute_reply": "2026-07-14T21:19:48.623192Z"
}
},
"outputs": [
Expand Down Expand Up @@ -158,10 +158,10 @@
"id": "4e61ac58",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:49.452228Z",
"iopub.status.busy": "2026-07-14T19:10:49.451965Z",
"iopub.status.idle": "2026-07-14T19:10:51.127557Z",
"shell.execute_reply": "2026-07-14T19:10:51.126450Z"
"iopub.execute_input": "2026-07-14T21:19:48.626932Z",
"iopub.status.busy": "2026-07-14T21:19:48.626645Z",
"iopub.status.idle": "2026-07-14T21:19:50.237430Z",
"shell.execute_reply": "2026-07-14T21:19:50.236217Z"
}
},
"outputs": [],
Expand Down Expand Up @@ -219,10 +219,10 @@
"id": "0de9e002",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:51.130731Z",
"iopub.status.busy": "2026-07-14T19:10:51.130441Z",
"iopub.status.idle": "2026-07-14T19:10:51.148445Z",
"shell.execute_reply": "2026-07-14T19:10:51.147133Z"
"iopub.execute_input": "2026-07-14T21:19:50.240462Z",
"iopub.status.busy": "2026-07-14T21:19:50.240142Z",
"iopub.status.idle": "2026-07-14T21:19:50.259191Z",
"shell.execute_reply": "2026-07-14T21:19:50.257902Z"
}
},
"outputs": [
Expand Down Expand Up @@ -368,10 +368,10 @@
"id": "72275c7f",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:51.151166Z",
"iopub.status.busy": "2026-07-14T19:10:51.150892Z",
"iopub.status.idle": "2026-07-14T19:10:51.174015Z",
"shell.execute_reply": "2026-07-14T19:10:51.172684Z"
"iopub.execute_input": "2026-07-14T21:19:50.262765Z",
"iopub.status.busy": "2026-07-14T21:19:50.262453Z",
"iopub.status.idle": "2026-07-14T21:19:50.331965Z",
"shell.execute_reply": "2026-07-14T21:19:50.330701Z"
}
},
"outputs": [
Expand Down Expand Up @@ -515,10 +515,10 @@
"id": "054959bf",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:51.176540Z",
"iopub.status.busy": "2026-07-14T19:10:51.176217Z",
"iopub.status.idle": "2026-07-14T19:10:51.183444Z",
"shell.execute_reply": "2026-07-14T19:10:51.181999Z"
"iopub.execute_input": "2026-07-14T21:19:50.334898Z",
"iopub.status.busy": "2026-07-14T21:19:50.334601Z",
"iopub.status.idle": "2026-07-14T21:19:50.341525Z",
"shell.execute_reply": "2026-07-14T21:19:50.340259Z"
}
},
"outputs": [
Expand Down Expand Up @@ -554,10 +554,10 @@
"id": "591930bf",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:51.186313Z",
"iopub.status.busy": "2026-07-14T19:10:51.186040Z",
"iopub.status.idle": "2026-07-14T19:10:51.593042Z",
"shell.execute_reply": "2026-07-14T19:10:51.591820Z"
"iopub.execute_input": "2026-07-14T21:19:50.344474Z",
"iopub.status.busy": "2026-07-14T21:19:50.344084Z",
"iopub.status.idle": "2026-07-14T21:19:51.186802Z",
"shell.execute_reply": "2026-07-14T21:19:51.185538Z"
}
},
"outputs": [
Expand Down Expand Up @@ -596,10 +596,10 @@
"id": "a8fa7702",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:51.596645Z",
"iopub.status.busy": "2026-07-14T19:10:51.596329Z",
"iopub.status.idle": "2026-07-14T19:10:52.049139Z",
"shell.execute_reply": "2026-07-14T19:10:52.047728Z"
"iopub.execute_input": "2026-07-14T21:19:51.189656Z",
"iopub.status.busy": "2026-07-14T21:19:51.189220Z",
"iopub.status.idle": "2026-07-14T21:19:51.643855Z",
"shell.execute_reply": "2026-07-14T21:19:51.642662Z"
}
},
"outputs": [
Expand Down Expand Up @@ -640,10 +640,10 @@
"id": "fe136f2f",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:52.052238Z",
"iopub.status.busy": "2026-07-14T19:10:52.051940Z",
"iopub.status.idle": "2026-07-14T19:10:52.725521Z",
"shell.execute_reply": "2026-07-14T19:10:52.724140Z"
"iopub.execute_input": "2026-07-14T21:19:51.646977Z",
"iopub.status.busy": "2026-07-14T21:19:51.646688Z",
"iopub.status.idle": "2026-07-14T21:19:52.330554Z",
"shell.execute_reply": "2026-07-14T21:19:52.329454Z"
}
},
"outputs": [
Expand Down Expand Up @@ -680,10 +680,10 @@
"id": "6ab2203a",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:52.729596Z",
"iopub.status.busy": "2026-07-14T19:10:52.729111Z",
"iopub.status.idle": "2026-07-14T19:10:53.260060Z",
"shell.execute_reply": "2026-07-14T19:10:53.258780Z"
"iopub.execute_input": "2026-07-14T21:19:52.334811Z",
"iopub.status.busy": "2026-07-14T21:19:52.334353Z",
"iopub.status.idle": "2026-07-14T21:19:52.834136Z",
"shell.execute_reply": "2026-07-14T21:19:52.832893Z"
}
},
"outputs": [
Expand Down Expand Up @@ -725,10 +725,10 @@
"id": "facae961",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:53.263937Z",
"iopub.status.busy": "2026-07-14T19:10:53.263606Z",
"iopub.status.idle": "2026-07-14T19:10:53.596257Z",
"shell.execute_reply": "2026-07-14T19:10:53.595263Z"
"iopub.execute_input": "2026-07-14T21:19:52.836950Z",
"iopub.status.busy": "2026-07-14T21:19:52.836652Z",
"iopub.status.idle": "2026-07-14T21:19:53.180973Z",
"shell.execute_reply": "2026-07-14T21:19:53.179559Z"
}
},
"outputs": [
Expand Down Expand Up @@ -767,10 +767,10 @@
"id": "f710be3d",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:53.600242Z",
"iopub.status.busy": "2026-07-14T19:10:53.599959Z",
"iopub.status.idle": "2026-07-14T19:10:55.886460Z",
"shell.execute_reply": "2026-07-14T19:10:55.883097Z"
"iopub.execute_input": "2026-07-14T21:19:53.184063Z",
"iopub.status.busy": "2026-07-14T21:19:53.183740Z",
"iopub.status.idle": "2026-07-14T21:19:55.358728Z",
"shell.execute_reply": "2026-07-14T21:19:55.357457Z"
}
},
"outputs": [
Expand Down Expand Up @@ -831,10 +831,10 @@
"id": "122cfeea",
"metadata": {
"execution": {
"iopub.execute_input": "2026-07-14T19:10:55.890574Z",
"iopub.status.busy": "2026-07-14T19:10:55.890147Z",
"iopub.status.idle": "2026-07-14T19:10:56.057809Z",
"shell.execute_reply": "2026-07-14T19:10:56.056266Z"
"iopub.execute_input": "2026-07-14T21:19:55.362288Z",
"iopub.status.busy": "2026-07-14T21:19:55.361948Z",
"iopub.status.idle": "2026-07-14T21:19:55.368105Z",
"shell.execute_reply": "2026-07-14T21:19:55.366668Z"
}
},
"outputs": [
Expand All @@ -843,27 +843,25 @@
"output_type": "stream",
"text": [
"python: 3.12.13 | packaged by conda-forge | (main, Mar 5 2026, 16:50:00) [GCC 14.3.0]\n",
"selectsim: 0.2.0\n",
"selectsim: 0.3.0\n",
"numpy: 2.1.3\n",
"pandas: 2.2.3\n",
"scipy: 1.14.1\n",
"matplotlib: 3.11.0\n",
"seaborn: 0.13.2\n"
"matplotlib: 3.11.0\n"
]
}
],
"source": [
"import sys\n",
"import numpy, pandas, scipy, matplotlib, seaborn\n",
"import numpy, pandas, scipy, matplotlib\n",
"import selectsim\n",
"\n",
"print(\"python:\", sys.version)\n",
"print(\"selectsim:\", selectsim.__version__)\n",
"print(\"numpy:\", numpy.__version__)\n",
"print(\"pandas:\", pandas.__version__)\n",
"print(\"scipy:\", scipy.__version__)\n",
"print(\"matplotlib:\", matplotlib.__version__)\n",
"print(\"seaborn:\", seaborn.__version__)"
"print(\"matplotlib:\", matplotlib.__version__)"
]
}
],
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "selectsim"
version = "0.3.0"
version = "0.3.1"
description = "A python package that implements the SelectSim algorithm"
authors = [
{ name = "Arvind Iyer", email = "ayalurarvind@gmail.com" },
Expand All @@ -22,7 +22,6 @@ dependencies = [
"tqdm>=4.66.0,<5",
"pyarrow>=18.0.0,<19",
"matplotlib>=3.9.0,<4",
"seaborn>=0.13.0,<0.14",
]

[project.urls]
Expand Down
43 changes: 32 additions & 11 deletions selectsim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,14 @@
stat_maf_gene,
maf_to_gam
)
from selectsim.plotting import (
theme_publication,
obs_exp_scatter,
significance_heatmap,
overlap_pair_extract,
ridge_plot_ed,
ridge_plot_ed_compare,
oncoprint_pair,
oncoprint
)
from selectsim.io import (
read_parquet,
write_parquet,
create_zarr_null_store,
open_zarr_store
)

__version__ = "0.3.0"
__version__ = "0.3.1"

__all__ = [
# Main function
Expand Down Expand Up @@ -133,3 +123,34 @@
"create_zarr_null_store",
"open_zarr_store",
]

# Plotting functions are resolved lazily (PEP 562), rather than imported
# eagerly above like everything else: selectsim.plotting pulls in
# matplotlib and scipy (measured ~1s import overhead combined, mostly
# matplotlib.pyplot) -- overhead every `import selectsim` would otherwise
# pay even for pure-computation use (e.g. just calling selectX()) that
# never touches a plotting function. scipy is in fact used nowhere
# outside plotting.py either. Deferring the import to first access of one
# of these names (only) keeps `selectsim.<plotting name>` working exactly
# as before, without forcing the cost on callers who never ask for it.
_LAZY_PLOTTING_ATTRS = frozenset({
"theme_publication",
"obs_exp_scatter",
"significance_heatmap",
"overlap_pair_extract",
"ridge_plot_ed",
"ridge_plot_ed_compare",
"oncoprint_pair",
"oncoprint",
})


def __getattr__(name):
if name in _LAZY_PLOTTING_ATTRS:
from selectsim import plotting
return getattr(plotting, name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


def __dir__():
return sorted(set(globals()) | _LAZY_PLOTTING_ATTRS)
6 changes: 3 additions & 3 deletions selectsim/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

Python port of ``R/selectX_plot.R``. The R implementation is built on
``ggplot2``/``ggpubr``/``ggridges``; this module reproduces the same visual
intent using ``matplotlib`` + ``seaborn`` (the library choice made for the
Python port), since no display is assumed to be available.
intent using ``matplotlib`` (the library choice made for the Python port),
since no display is assumed to be available.

Functions
---------
Expand Down Expand Up @@ -503,7 +503,7 @@ def ridge_plot_ed(
Implementation note: this is the standard "joyplot"/ridgeline technique
-- per-row Gaussian KDEs evaluated on a shared x-grid and stacked with a
constant y-offset -- rather than ``ggridges::geom_density_ridges``,
since matplotlib/seaborn has no ridge-plot geom built in.
since matplotlib has no ridge-plot geom built in.

Parameters
----------
Expand Down
Loading