Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
4c7767c
WIP accessors
flying-sheep Jan 8, 2026
5103b0d
fix: AdPath oversight
flying-sheep Jan 9, 2026
6878fc3
chore: more API
flying-sheep Jan 9, 2026
c24206a
tests
flying-sheep Jan 9, 2026
6ffcb29
fix equality
flying-sheep Jan 9, 2026
05d0900
move parsing out
flying-sheep Jan 9, 2026
61fc920
parse all
flying-sheep Jan 9, 2026
809ad8d
tests
flying-sheep Jan 12, 2026
95b35a6
Merge branch 'main' into pa/acc
flying-sheep Jan 12, 2026
b95b3b9
pattern matching
flying-sheep Jan 12, 2026
63d0d87
simpler
flying-sheep Jan 12, 2026
85a9a51
WIP docs
flying-sheep Jan 15, 2026
f83fc85
fix tests
flying-sheep Jan 15, 2026
3943f19
warnings
flying-sheep Jan 15, 2026
e4e6c37
move types up
flying-sheep Jan 15, 2026
8054045
adref
flying-sheep Jan 15, 2026
1261d84
mostly fix docs
flying-sheep Jan 15, 2026
fa7f136
really fix docs
flying-sheep Jan 15, 2026
0aa542c
fix test
flying-sheep Jan 15, 2026
7c98c49
rename all the things
flying-sheep Jan 16, 2026
bf1d630
bit more explicit
flying-sheep Jan 16, 2026
f279003
Merge branch 'main' into pa/acc
flying-sheep Jan 26, 2026
f7ea522
WIP
flying-sheep Jan 27, 2026
3652c2e
Merge branch 'main' into pa/acc
flying-sheep Jan 27, 2026
fdc3ed8
ext metadata
flying-sheep Jan 27, 2026
4a8a636
works!
flying-sheep Jan 27, 2026
b967e4c
Merge branch 'main' into pa/acc
flying-sheep Jan 27, 2026
f47fd37
JSON parser
flying-sheep Jan 27, 2026
ff123d3
simplify
flying-sheep Jan 27, 2026
af846f8
test serialization
flying-sheep Jan 27, 2026
588a6b6
add examples for all vector accessors
flying-sheep Jan 29, 2026
30407a3
Merge branch 'main' into pa/acc
flying-sheep Jan 29, 2026
7f7b0be
also allow pandas index
flying-sheep Jan 29, 2026
c7abcd5
Merge branch 'main' into pa/acc
flying-sheep Jan 30, 2026
9dc9975
add schema
flying-sheep Jan 30, 2026
c804f70
schema in docs
flying-sheep Jan 30, 2026
c4799b0
feat: working __contains__
flying-sheep Feb 2, 2026
2a7fc64
ax→dim
flying-sheep Feb 2, 2026
8dc8d07
typeerror on `in` check
flying-sheep Feb 2, 2026
ad2e4a2
v1
flying-sheep Feb 5, 2026
d524c3c
deprecate obs_vector and var_vector
flying-sheep Feb 6, 2026
f1c0fe4
rebase {obs,var}_vector
flying-sheep Feb 6, 2026
006fdb5
get tests
flying-sheep Feb 6, 2026
170606e
Merge branch 'main' into pa/acc
flying-sheep Feb 6, 2026
7d76636
dask
flying-sheep Feb 6, 2026
28b7897
nomenclature
flying-sheep Feb 6, 2026
affb0dd
cupy
flying-sheep Feb 6, 2026
77f4a2d
docs
flying-sheep Feb 6, 2026
821762f
yq
flying-sheep Feb 6, 2026
951bc9b
yq
flying-sheep Feb 6, 2026
6dc5d13
fix tests
flying-sheep Feb 6, 2026
afdc446
docs: ref
flying-sheep Feb 9, 2026
f41f611
Merge branch 'main' into pa/acc
flying-sheep Feb 9, 2026
a53771a
array-api
flying-sheep Feb 9, 2026
e433ce8
Idx2D docs
flying-sheep Feb 9, 2026
366034b
style
flying-sheep Feb 9, 2026
fc1e057
fix docs
flying-sheep Feb 9, 2026
899126e
Merge branch 'main' into pa/acc
flying-sheep Feb 9, 2026
d8bae96
change getter API
flying-sheep Feb 10, 2026
e5493a5
more examples
flying-sheep Feb 10, 2026
7aaa1cd
extension docs
flying-sheep Feb 10, 2026
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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": [
"--color=yes",
"-vv",
"-vvv",
"--strict-warnings",
//"-nauto",
],
"python.terminal.activateEnvironment": true,
"python.analysis.include": ["src/**/*", "ci/scripts/**/*", "tests/**/*"],
}
198 changes: 198 additions & 0 deletions docs/accessors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
.. _accessors:

Accessors and paths
===================

.. module:: anndata.acc

:mod:`!anndata.acc` creates references to 1D and 2D arrays in an :class:`~anndata.AnnData` object.
You can use these to drive e.g. plotting or validation code.
For these purposes, they are

#. easy to create:

The central :attr:`A` object allows you to create
:class:`AdRef` objects that reference arrays
along one or two dimensions of an :class:`~anndata.AnnData` object:

>>> from anndata.acc import A
>>> A[:, "gene-3"] # reference to `adata[:, "gene-3"].X` as 1D vector
A[:, 'gene-3']
>>> type(A[:, "gene-3"])
<class 'anndata.acc.AdRef'>

… and to use:

>>> import scanpy as sc
>>> adata = sc.datasets.pbmc3k_processed()

E.g. to check if `adata.varm["PCs"]` has at least 30 columns:

>>> A.varm["PCs"][:, 30] in adata
True

or to extract the referenced vector:

>>> ref = A.obs["louvain"]
>>> adata[ref].categories[:2]
Index(['CD4 T cells', 'CD14+ Monocytes'], dtype='str')

#. introspectible:

:class:`AdRef`\ s have the :attr:`AdRef.dims`, :attr:`AdRef.idx`, and :attr:`AdRef.acc` attributes,
allowing you to inspect all relevant properties.

>>> pc0 = A.obsm["pca"][:, 0]
>>> pc0
A.obsm['pca'][:, 0]
>>> pc0.idx
0
>>> pc0.acc
A.obsm['pca']
>>> A.var["symbol"].dims
{'var'}
>>> pc0.acc.k
'pca'

#. convenient:

Want to reference multiple vectors from the same object?
Pass a list of indices to the vector accessor:

>>> A.obsp["connectivities"][:, ["cell0", "cell1"]]
[A.obsp['connectivities'][:, 'cell0'], A.obsp['connectivities'][:, 'cell1']]

#. extensible: see `extending accessors`_.

API
---

The central starting point is :data:`!A`:

.. autodata:: A

See :class:`AdAcc` for examples of how to use it to create :attr:`AdRef`\ s.

.. autosummary::
:toctree: generated/
:template: class-minimal

AdRef

.. _reference accessors:

Reference accessors
~~~~~~~~~~~~~~~~~~~

The following :class:`!RefAcc` subclasses can be accessed using :attr:`AdRef.acc`,
and are therefore useful in :ref:`matches <match>` or :func:`isinstance` checks:

.. autosummary::
:toctree: generated/
:template: class-minimal

RefAcc

.. list-table::
:header-rows: 1

- - Class
- Attributes
- Examples
- - :class:`AdAcc`
- is a :class:`LayerAcc` with `.k=None`
- `A["c1", :]`, `A[:, "g1"]`, `A[:, :]`
- - :class:`LayerAcc`
- :attr:`LayerAcc.k`
- `A.layers["c"][:, "g0"]`
- - :class:`MetaAcc`
- :attr:`MetaAcc.dim`
- `A.obs["a"]`, `A.var["b"]`
- - :class:`MultiAcc`
- :attr:`MultiAcc.dim`, :attr:`MultiAcc.k`
- `A.obsm["d"][:, 2]`
- - :class:`GraphAcc`
- :attr:`GraphAcc.dim`, :attr:`GraphAcc.k`
- `A.obsp["e"][:, "c1"]`, `A.vbsp["e"]["g0", :]`

.. hidden
.. autosummary::
:toctree: generated/
:template: class-minimal

AdAcc
LayerAcc
MetaAcc
MultiAcc
GraphAcc

.. autosummary::
:toctree: generated/

Idx2D

.. toctree::
:hidden:

generated/anndata.acc.AdAcc
generated/anndata.acc.LayerAcc
generated/anndata.acc.MetaAcc
generated/anndata.acc.MultiAcc
generated/anndata.acc.GraphAcc
generated/anndata.acc.Idx2D

Mapping accessors
~~~~~~~~~~~~~~~~~

Finally, these classes are mostly useful for extending,
but might be useful for APIs that take a reference to a :class:`collections.abc.Mapping`
of arrays:

.. autosummary::
:toctree: generated/
:template: class-minimal

MapAcc
LayerMapAcc
MultiMapAcc
GraphMapAcc

.. _extending accessors:

Extending accessors
-------------------

There are three layers of extensibility:

#. subclassing :class:`RefAcc` and creating a new :class:`AdRef` instance for creating them:

.. code-block:: python

import my_plotting_library as pl

class AdDim(RefAcc, pl.Dimension): ...
A = AdAcc(ref_class=AdDim)

pl.scatter(adata, A[:, "Actb"], color=A.obs["cell_type"])


#. subclass one or more of the `reference accessors`_, and create a new :class:`AdAcc` instance:

>>> from anndata.acc import AdAcc, AdRef, MetaAcc
>>>
>>> class TwoDRef(AdRef):
... """A reference able to refer to multiple metadata columns."""
... ...
>>>
>>> class MyMetaAcc(MetaAcc):
... def __getitem__(self, k):
... if isinstance(k, list):
... # override default behavior of returning a list of refs
... return self.ref_class(self, k)
... return super().__getitem__(k)
>>>
>>> A = AdAcc(ref_class=TwoDRef, meta_cls=MyMetaAcc)
>>> A.obs[["a", "b"]]
A.obs[['a', 'b']]

#. .. attention:: TODO
11 changes: 11 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ The central class:
AnnData
```

Its attributes are reflected in the {doc}`/accessors` API ({mod}`!anndata.acc`).
If you want to write e.g. plotting or validation code for anndata objects, look there!

```{eval-rst}
.. toctree::
:hidden:

anndata.acc <accessors>
```

(combining-api)=

## Combining
Expand Down Expand Up @@ -266,6 +276,7 @@ Types used by the former:

typing.Index1D
typing.Index
typing.InMemoryArray
typing.AxisStorable
typing.RWAble
```
8 changes: 6 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

HERE = Path(__file__).parent
_extension_dir = HERE / "extensions"
acc_schema = HERE.parent / "src/anndata/acc/acc-schema-v1.json"
sys.path[:0] = [str(_extension_dir)]


Expand All @@ -28,6 +29,7 @@
# default settings
templates_path = ["_templates"]
html_static_path = ["_static"]
html_extra_path = [str(acc_schema)]
source_suffix = {".rst": "restructuredtext", ".md": "myst-nb"}
master_doc = "index"
default_role = "literal"
Expand Down Expand Up @@ -74,7 +76,7 @@
autosummary_generate = True
autodoc_member_order = "bysource"
autodoc_mock_imports = ["torch"]
# autodoc_default_flags = ['members']
# autodoc_default_options = {}
issues_github_path = "scverse/anndata"
rtd_links_prefix = PurePosixPath("src")
napoleon_google_docstring = False
Expand Down Expand Up @@ -174,7 +176,9 @@ def res(
("py:class", "pandas.api.typing.NAType"),
# TODO: remove zappy support; the zappy repo is archived
("py:class", "anndata.compat.ZappyArray"),
# Type variable for internal use
# this happens when a `type` or `class` is generic
("py:class", "anndata.acc.GenericAlias"),
("py:obj", "typing.R"),
("py:class", "_M"),
]

Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/0.6.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

- better support for aligned mappings (obsm, varm, layers)
`0.6.22` {pr}`155` {smaller}`I Virshup`
- convenience accessors {func}`~anndata.AnnData.obs_vector`, {func}`~anndata.AnnData.var_vector` for 1d arrays.
- convenience accessors `AnnData.obs_vector`, `AnnData.var_vector` for 1d arrays.
`0.6.21` {pr}`144` {smaller}`I Virshup`
- compatibility with Scipy >=1.3 by removing `IndexMixin` dependency.
`0.6.20` {pr}`151` {smaller}`P Angerer`
Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/0.7.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#### Bug fixes

- Fixed inplace modification of {class}`~pandas.Index` objects by the make unique function {pr}`348` {smaller}`I Virshup`
- Passing ambiguous keys to {meth}`~anndata.AnnData.obs_vector` and {meth}`~anndata.AnnData.var_vector` now throws errors {pr}`340` {smaller}`I Virshup`
- Passing ambiguous keys to `AnnData.obs_vector` and `AnnData.var_vector` now throws errors {pr}`340` {smaller}`I Virshup`
- Fix instantiating {class}`~anndata.AnnData` objects from {class}`~pandas.DataFrame` {pr}`316` {smaller}`P Angerer`
- Fixed indexing into `AnnData` objects with arrays like `adata[adata[:, gene].X > 0]` {pr}`332` {smaller}`I Virshup`
- Fixed type of version {pr}`315` {smaller}`P Angerer`
Expand Down
1 change: 1 addition & 0 deletions docs/typing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

.. autotype:: Index1D
.. autotype:: Index
.. autotype:: InMemoryArray
.. autotype:: AxisStorable
.. autotype:: RWAble
```
15 changes: 10 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ doc = [
"IPython", # For syntax highlighting in notebooks
"myst-parser",
"sphinx-design",
"holoviews",
"anndata[dask]",
"pandas>=3",
# for unreleased changes
Expand All @@ -82,6 +83,7 @@ dev-doc = [
]
test = [
"fast-array-utils>=1.2.3",
"holoviews",
"anndata[lazy]",
{ include-group = "test-min" },
]
Expand All @@ -93,6 +95,7 @@ test-min = [
"pytest-mock",
"pytest-xdist[psutil]",
"filelock",
"jsonschema",
"matplotlib",
"scikit-learn",
"openpyxl",
Expand Down Expand Up @@ -181,10 +184,12 @@ filterwarnings_when_strict = [
]
python_files = [ "test_*.py" ]
testpaths = [
"anndata", # docstrings (module name due to --pyargs)
"./tests", # unit tests
"./ci/scripts", # CI script tests
"./docs/concatenation.rst", # further doctests
"anndata", # docstrings (module name due to --pyargs)
"./tests", # unit tests
"./ci/scripts", # CI script tests
# further doctests
"./docs/accessors.rst",
"./docs/concatenation.rst",
]
# For some reason this effects how logging is shown when tests are run
markers = [
Expand Down Expand Up @@ -226,7 +231,7 @@ select = [
"UP", # pyupgrade
"W", # Warning detected by Pycodestyle
]
external = [ "PLR0917" ] # preview rule
external = [ "PLR0917", "PLW0108" ] # preview rules
ignore = [
"C408", # dict() syntax is preferable for dicts used as kwargs
"E501", # line too long -> we accept long comment lines; formatter gets rid of long code lines
Expand Down
3 changes: 2 additions & 1 deletion src/anndata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .utils import module_get_attr_redirect, warn

# Submodules need to be imported last
from . import abc, experimental, typing, io, types # isort: skip
from . import abc, acc, experimental, io, types, typing # isort: skip

# We use these in tests by attribute access
from . import logging # noqa: F401 # isort: skip
Expand All @@ -35,6 +35,7 @@
"Raw",
"WriteWarning",
"abc",
"acc",
"concat",
"experimental",
"io",
Expand Down
Loading
Loading