# Python Integration with anndataR

#### 18 May 2026

#### Package

anndataR 1.3.0

# Contents

# 1 Introduction

anndataR works with Python `AnnData` objects through reticulate. You can load Python objects, apply Python functions to them, and convert them to `Seurat` or `SingleCellExperiment` objects.

    message(
      "Python packages scanpy and mudata are required to run this vignette. Code chunks will not be evaluated."
    )

## 1.1 Prerequisites

This vignette requires Python with the scanpy and mudata packages installed. If these are not available, the code chunks will not be evaluated but the examples remain visible.

# 2 Basic Integration with scanpy

Install required Python packages if needed:

    reticulate::py_require("scanpy")

    library(anndataR)
    library(reticulate)
    sc <- import("scanpy")

Load a dataset directly from scanpy:

    adata <- sc$datasets$pbmc3k_processed()
    adata
    #> ReticulateAnnData object with n_obs × n_vars = 2638 × 1838
    #>     obs: 'n_genes', 'percent_mito', 'n_counts', 'louvain'
    #>     var: 'n_cells'
    #>     uns: 'draw_graph', 'louvain', 'louvain_colors', 'neighbors', 'pca', 'rank_genes_groups'
    #>     obsm: 'X_pca', 'X_tsne', 'X_umap', 'X_draw_graph_fr'
    #>     varm: 'PCs'
    #>     obsp: 'distances', 'connectivities'

Apply scanpy functions directly:

    sc$pp$filter_cells(adata, min_genes = 200L)
    sc$pp$normalize_total(adata, target_sum = 1e4)
    sc$pp$log1p(adata)

# 3 Conversion to R objects

Convert to `SingleCellExperiment` (see `vignette("usage_singlecellexperiment")`):

    sce_obj <- adata$as_SingleCellExperiment()
    sce_obj
    #> class: SingleCellExperiment
    #> dim: 1838 538
    #> metadata(7): draw_graph louvain ... rank_genes_groups log1p
    #> assays(1): X
    #> rownames(1838): TNFRSF4 CPSF3L ... S100B PRMT2
    #> rowData names(1): n_cells
    #> colnames(538): AAACATTGAGCTAC-1 AAACATTGATCAGC-1 ... TTTCGAACTCTCAT-1
    #>   TTTCTACTGAGGCA-1
    #> colData names(4): n_genes percent_mito n_counts louvain
    #> reducedDimNames(4): X_pca X_tsne X_umap X_draw_graph_fr
    #> mainExpName: NULL
    #> altExpNames(0):

Convert to `Seurat` (see `vignette("usage_seurat")`):

    seurat_obj <- adata$as_Seurat()
    #> Warning: No "counts" or "data" layer found in `names(layers_mapping)`, this may lead to
    #> unexpected results when using the resulting <Seurat> object.
    #> Warning: Data is of class matrix. Coercing to dgCMatrix.
    seurat_obj
    #> An object of class Seurat
    #> 1838 features across 538 samples within 1 assay
    #> Active assay: RNA (1838 features, 0 variable features)
    #>  1 layer present: X
    #>  4 dimensional reductions calculated: X_pca, X_tsne, X_umap, X_draw_graph_fr

# 4 Multi-modal data with mudata

Install required Python packages if needed:

    reticulate::py_install("mudata")

    md <- import("mudata")

Load a `MuData` object from file:

    cache <- BiocFileCache::BiocFileCache(ask = FALSE)
    h5mu_file <- BiocFileCache::bfcrpath(
      cache,
      "https://github.com/gtca/h5xx-datasets/raw/b1177ac8877c89d8bb355b072164384b4e9cc81d/datasets/minipbcite.h5mu"
    )
    #> adding rname 'https://github.com/gtca/h5xx-datasets/raw/b1177ac8877c89d8bb355b072164384b4e9cc81d/datasets/minipbcite.h5mu'

    mdata <- md$read_h5mu(h5mu_file)

Access individual modalities and convert them:

    rna_mod <- mdata$mod[["rna"]]

    rna_seurat <- rna_mod$as_Seurat()
    #> Warning: No "counts" or "data" layer found in `names(layers_mapping)`, this may lead to
    #> unexpected results when using the resulting <Seurat> object.
    #> Warning: Data is of class matrix. Coercing to dgCMatrix.
    print(rna_seurat)
    #> An object of class Seurat
    #> 27 features across 411 samples within 1 assay
    #> Active assay: RNA (27 features, 0 variable features)
    #>  1 layer present: X
    #>  2 dimensional reductions calculated: X_pca, X_umap

    rna_sce <- rna_mod$as_SingleCellExperiment()
    print(rna_sce)
    #> class: SingleCellExperiment
    #> dim: 27 411
    #> metadata(8): celltype_colors hvg ... rank_genes_groups umap
    #> assays(1): X
    #> rownames(27): NKG7 KLRC2 ... MS4A1 KLF4
    #> rowData names(13): gene_ids feature_types ... mean std
    #> colnames(411): CAGCCAGGTCTCGACG-1 TTCTTCCTCTCGGTAA-1 ...
    #>   GACTCTCCAGCTCTGG-1 GAAATGACAAGCACCC-1
    #> colData names(6): n_genes_by_counts total_counts ... leiden celltype
    #> reducedDimNames(2): X_pca X_umap
    #> mainExpName: NULL
    #> altExpNames(0):

# 5 Session info

## 5.1 R

    sessionInfo()
    #> R version 4.6.0 Patched (2026-05-01 r89994)
    #> Platform: aarch64-apple-darwin23
    #> Running under: macOS Tahoe 26.3.1
    #>
    #> Matrix products: default
    #> BLAS:   /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
    #> LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
    #>
    #> locale:
    #> [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    #>
    #> time zone: America/New_York
    #> tzcode source: internal
    #>
    #> attached base packages:
    #> [1] stats4    stats     graphics  grDevices utils     datasets  methods
    #> [8] base
    #>
    #> other attached packages:
    #>  [1] reticulate_1.46.0           anndataR_1.3.0
    #>  [3] SingleCellExperiment_1.35.1 SummarizedExperiment_1.43.0
    #>  [5] Biobase_2.73.1              GenomicRanges_1.65.0
    #>  [7] Seqinfo_1.3.0               IRanges_2.47.1
    #>  [9] S4Vectors_0.51.2            BiocGenerics_0.59.2
    #> [11] generics_0.1.4              MatrixGenerics_1.25.0
    #> [13] matrixStats_1.5.0           SeuratObject_5.4.0
    #> [15] sp_2.2-1                    BiocStyle_2.41.0
    #>
    #> loaded via a namespace (and not attached):
    #>   [1] RColorBrewer_1.1-3     jsonlite_2.0.0         magrittr_2.0.5
    #>   [4] spatstat.utils_3.2-3   farver_2.1.2           rmarkdown_2.31
    #>   [7] vctrs_0.7.3            ROCR_1.0-12            memoise_2.0.1
    #>  [10] spatstat.explore_3.8-0 htmltools_0.5.9        S4Arrays_1.13.0
    #>  [13] curl_7.1.0             Rhdf5lib_2.1.0         SparseArray_1.13.2
    #>  [16] rhdf5_2.57.0           sass_0.4.10            sctransform_0.4.3
    #>  [19] parallelly_1.47.0      KernSmooth_2.23-26     bslib_0.11.0
    #>  [22] htmlwidgets_1.6.4      ica_1.0-3              httr2_1.2.2
    #>  [25] plyr_1.8.9             plotly_4.12.0          zoo_1.8-15
    #>  [28] cachem_1.1.0           igraph_2.3.1           mime_0.13
    #>  [31] lifecycle_1.0.5        pkgconfig_2.0.3        Matrix_1.7-5
    #>  [34] R6_2.6.1               fastmap_1.2.0          fitdistrplus_1.2-6
    #>  [37] future_1.70.0          shiny_1.13.0           digest_0.6.39
    #>  [40] paws.storage_0.9.0     patchwork_1.3.2        Seurat_5.5.0
    #>  [43] tensor_1.5.1           RSpectra_0.16-2        irlba_2.3.7
    #>  [46] RSQLite_3.52.0         filelock_1.0.3         Rarr_2.1.8
    #>  [49] progressr_0.19.0       spatstat.sparse_3.1-0  httr_1.4.8
    #>  [52] polyclip_1.10-7        abind_1.4-8            compiler_4.6.0
    #>  [55] bit64_4.8.0            withr_3.0.2            S7_0.2.2
    #>  [58] DBI_1.3.0              fastDummies_1.7.6      R.utils_2.13.0
    #>  [61] MASS_7.3-65            rappdirs_0.3.4         DelayedArray_0.39.2
    #>  [64] tools_4.6.0            lmtest_0.9-40          otel_0.2.0
    #>  [67] httpuv_1.6.17          future.apply_1.20.2    goftest_1.2-3
    #>  [70] R.oo_1.27.1            glue_1.8.1             nlme_3.1-169
    #>  [73] rhdf5filters_1.25.0    promises_1.5.0         grid_4.6.0
    #>  [76] Rtsne_0.17             cluster_2.1.8.2        reshape2_1.4.5
    #>  [79] gtable_0.3.6           spatstat.data_3.1-9    R.methodsS3_1.8.2
    #>  [82] tidyr_1.3.2            data.table_1.18.4      XVector_0.53.0
    #>  [85] spatstat.geom_3.7-3    RcppAnnoy_0.0.23       ggrepel_0.9.8
    #>  [88] RANN_2.6.2             pillar_1.11.1          stringr_1.6.0
    #>  [91] spam_2.11-3            RcppHNSW_0.6.0         later_1.4.8
    #>  [94] splines_4.6.0          dplyr_1.2.1            BiocFileCache_3.3.0
    #>  [97] lattice_0.22-9         bit_4.6.0              survival_3.8-6
    #> [100] deldir_2.0-4           paws.common_0.8.9      tidyselect_1.2.1
    #> [103] miniUI_0.1.2           pbapply_1.7-4          knitr_1.51
    #> [106] gridExtra_2.3          bookdown_0.46          scattermore_1.2
    #> [109] xfun_0.57              stringi_1.8.7          lazyeval_0.2.3
    #> [112] yaml_2.3.12            evaluate_1.0.5         codetools_0.2-20
    #> [115] tibble_3.3.1           BiocManager_1.30.27    cli_3.6.6
    #> [118] uwot_0.2.4             xtable_1.8-8           jquerylib_0.1.4
    #> [121] dichromat_2.0-0.1      Rcpp_1.1.1-1.1         globals_0.19.1
    #> [124] spatstat.random_3.4-5  dbplyr_2.5.2           png_0.1-9
    #> [127] spatstat.univar_3.2-0  parallel_4.6.0         blob_1.3.0
    #> [130] ggplot2_4.0.3          dotCall64_1.2          listenv_0.10.1
    #> [133] viridisLite_0.4.3      scales_1.4.0           ggridges_0.5.7
    #> [136] crayon_1.5.3           purrr_1.2.2            rlang_1.2.0
    #> [139] cowplot_1.2.0

## 5.2 Python

    reticulate::py_config()
    #> python:         /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC/bin/python
    #> libpython:      /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/python/cpython-3.12.13-macos-aarch64-none/lib/libpython3.12.dylib
    #> pythonhome:     /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC:/Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC
    #> virtualenv:     /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC/bin/activate_this.py
    #> version:        3.12.13 (main, May 10 2026, 19:20:41) [Clang 22.1.3 ]
    #> numpy:          /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC/lib/python3.12/site-packages/numpy
    #> numpy_version:  2.4.5
    #> scanpy:         /Users/biocbuild/Library/Caches/org.R-project.R/R/reticulate/uv/cache/archive-v0/M5TGZGf33n0KKAcC/lib/python3.12/site-packages/scanpy
    #>
    #> NOTE: Python version was forced by py_require()

    reticulate::py_list_packages()
    #>              package     version                  requirement
    #> 1            anndata     0.12.16             anndata==0.12.16
    #> 2   array-api-compat      1.14.0     array-api-compat==1.14.0
    #> 3            certifi   2026.4.22           certifi==2026.4.22
    #> 4          contourpy       1.3.3             contourpy==1.3.3
    #> 5             cycler      0.12.1               cycler==0.12.1
    #> 6             donfig 0.8.1.post1          donfig==0.8.1.post1
    #> 7   fast-array-utils       1.4.1      fast-array-utils==1.4.1
    #> 8          fonttools      4.63.0            fonttools==4.63.0
    #> 9      google-crc32c       1.8.0         google-crc32c==1.8.0
    #> 10              h5py      3.16.0                 h5py==3.16.0
    #> 11            joblib       1.5.3                joblib==1.5.3
    #> 12        kiwisolver       1.5.0            kiwisolver==1.5.0
    #> 13   legacy-api-wrap         1.5         legacy-api-wrap==1.5
    #> 14          llvmlite      0.47.0             llvmlite==0.47.0
    #> 15        matplotlib      3.10.9           matplotlib==3.10.9
    #> 16            mudata       0.3.8                mudata==0.3.8
    #> 17           natsort       8.4.0               natsort==8.4.0
    #> 18          networkx       3.6.1              networkx==3.6.1
    #> 19             numba      0.65.1                numba==0.65.1
    #> 20         numcodecs      0.16.5            numcodecs==0.16.5
    #> 21             numpy       2.4.5                 numpy==2.4.5
    #> 22         packaging        26.2              packaging==26.2
    #> 23            pandas       2.3.3                pandas==2.3.3
    #> 24             patsy       1.0.2                 patsy==1.0.2
    #> 25            pillow      12.2.0               pillow==12.2.0
    #> 26       pynndescent       0.6.0           pynndescent==0.6.0
    #> 27         pyparsing       3.3.2             pyparsing==3.3.2
    #> 28   python-dateutil 2.9.0.post0 python-dateutil==2.9.0.post0
    #> 29              pytz      2026.2                 pytz==2026.2
    #> 30            pyyaml       6.0.3                pyyaml==6.0.3
    #> 31            scanpy      1.12.1               scanpy==1.12.1
    #> 32      scikit-learn       1.8.0          scikit-learn==1.8.0
    #> 33             scipy      1.17.1                scipy==1.17.1
    #> 34      scverse-misc       0.0.7          scverse-misc==0.0.7
    #> 35           seaborn      0.13.2              seaborn==0.13.2
    #> 36     session-info2       0.4.1         session-info2==0.4.1
    #> 37               six      1.17.0                  six==1.17.0
    #> 38       statsmodels      0.14.6          statsmodels==0.14.6
    #> 39     threadpoolctl       3.6.0         threadpoolctl==3.6.0
    #> 40              tqdm      4.67.3                 tqdm==4.67.3
    #> 41 typing-extensions      4.15.0    typing-extensions==4.15.0
    #> 42            tzdata      2026.2               tzdata==2026.2
    #> 43        umap-learn      0.5.12           umap-learn==0.5.12
    #> 44              zarr       3.2.1                  zarr==3.2.1