Giter Site home page Giter Site logo

pachterlab / voyager Goto Github PK

View Code? Open in Web Editor NEW
60.0 4.0 5.0 4.19 GB

From geospatial to spatial -omics

Home Page: https://pachterlab.github.io/voyager/

License: Artistic License 2.0

R 100.00%
bioconductor eda esda exploratory-data-analysis omics r r-package rstats spatial spatial-statistics

voyager's Introduction

From geospatial to spatial transcriptomics

Lifecycle: experimental BioC status codecov

This package brings the tradition of geospatial statistics to spatial omics by wrapping classical geospatial packages such as spdep and gstat to be used with the SpatialFeatureExperiment class, which extends SpatialExperiment with sf.

The companion website for this package includes vignettes that showcase the functionality of Voyager in the context of the Visium, Slide-seq V2, CosMx, Xenium, and MERFISH technologies.

Installation

This package is in Bioconductor version 3.16 and above. Install with

if (!requireNamespace("BiocManager")) install.packages("BiocManager")
BiocManager::install(version = "3.17") # Or a higher version in the future
BiocManager::install("Voyager")

The main branch in this repo is the release version. The development version of Voyager can be installed from GitHub with:

# install.packages("remotes")
remotes::install_github("pachterlab/voyager", ref = "devel")

Or from Bioconductor with:

BiocManager::install("Voyager", version = "devel")

For contributors

The whole git repo of this package is huge because of the large number of figures and Jupyter notebooks in the documentation website. To reduce download time and disk space usage, you may clone the devel branch only, so the documentation branches are not cloned:

git clone -b devel --single-branch https://github.com/pachterlab/voyager.git

voyager's People

Contributors

jwokaty avatar kayla-jackson avatar lakigigar avatar lambdamoses avatar lauraluebbert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

voyager's Issues

Vignette using multiple samples

This is actually more like a research project, since it requires further consideration of what to make of spatial statistics across samples and their comparison in case vs. control. Also what it means to compute the spatial statistics jointly across samples or separately with each sample. Requires pachterlab/SpatialFeatureExperiment#33

read/load image-based spatial transcriptomics

Hi there,

Thanks for implementing this nice package, bridging geospatial data analysis with spatial omics analysis! :)
Few questions, however these things are probably on your todo list already:

  • is there a direct way to read and load (eg, Vizgen data) to generate SFE object?
    Similar to Seurat Seurat::ReadVizgen() & Seurat::LoadVizgen()
    I could only find create-sfe-object-from-scratch
  • is there a plan to implement a wrapper or helper function to convert already existing Seurat object (including all spatial FOV) to SFE

As for Vizgen/Merscope, recent version provides only Cellpose output, eg :

cellpose_mosaic_space.parquet # mols coords in px
cellpose_micron_space.parquet # mols coords in µm
cellpose_cell_by_gene.csv
cellpose_cell_metadata.csv

Something that I added using sfarrow for Seurat obj.
for data loading
for segs

Thanks
A.

could not find function "calculateBivariate"

I am learning Spatial Transcriptomics, and I am currently learning how to use the Package ‘Voyager.’
I am having issues with the routine "calculateBivariate" after running the example on page 6 of the manual.
I am getting the following:

sfe <- sfe[,sfe$in_tissue]
sfe <- logNormCounts(sfe)
gs <- modelGeneVar(sfe)
hvgs <- getTopHVGs(gs, fdr.threshold = 0.01)
g <- colGraph(sfe, "visium") <- findVisiumGraph(sfe)
mat <- logcounts(sfe)[hvgs[1:5],]
df <- df2sf(spatialCoords(sfe), spatialCoordsNames(sfe))
out <- calculateBivariate(mat, type = "lee", listw = g)
Error in calculateBivariate(mat, type = "lee", listw = g) :
could not find function "calculateBivariate"

I am using RStudio Version 2023.03.0+386 (2023.03.0+386) on a mac.

Thank you

Plot rowGeometries

It can be part of plotSpatialFeature and plotLocalResult, with one argument for which row geometry and another for which genes to plot. Then burning question: what palette to use to color the genes? I suppose I'll use point shape (and possibly line type since I can't predict how row geometries are used) and throw an error when there're more genes specified than there are shapes.

I also feel like plotSpatialFeature has too many arguments. While it's acceptable in R (see pheatmap and Seurat's plotting functions), I get it that it's a code smell in other languages. At present which geometry goes on which layer is also pretty inflexible. I think I can introduce a syntax like in ggplot2, plotly, or tmap, to build the plot layer by layer. Something like

plotSpatialFeature(sfe) +
    lyr_colGeometry(aes(fill = Myh2), data = cellSeg) +
    lyr_annotGeometry(data = tissueBoundary, fill = NA, color = "black", linewidth = 0.3) +
    lyr_rowGeometry(data = txSpots, aes(shape = gene), subset = c("Myh2", "Myh7"))

This way it's less confusing to customize the plot to those already familiar with ggplot2 and it's easier to arrange the layers. I think I'll also use tidyeval to be consistent with ggplot2, to reduce confusion. ggplot2 is based on the tidy data philosophy. While there is tidyomics, SFE is more complicated than tidy data, so maybe I need to think more carefully about the philosophy behind the data structure. Sounds like a lot of work, so I'm not sure if I can get it done for Bioc 3.18.

Forthcoming spdep release seems to break Voyager

00check.log
testthat.Rout.zip

Please test your package with forthcoming spdep HEAD, main branch - I expect to release shortly, and BC packages are not picked up in regular reverse dependency checks (which are for CRAN, not BC). I see errors, but have no idea what your testthat usage expects. All the local conditional permutation functions are under active development and cannot be expected to have unchanging output. Please file isiues on spdep if need be. Do read r-spatial/spdep#124 for details on some changes. In test-univariate.R:215, the extra output column comes from 1). In test-univariate.R:225, it is probably dropping the return_internals= argument. I am sceptical about backward-facing unit tests (nothing upstream can ever change) anyway.

Also see https://r-spatial.org/book/15-Measures.html#measures-and-process-mis-specification with regard to your docs splash on Tobler.

Write alt text for vignette figures

At least for the Visium vignettes but ideally all vignettes. It's a lot of work since there are so many vignettes. Ideally there should be a way to sonify spatial data or convert to tactile.

Alt text resources:

Captions are best when you're describing complex images (like diagrams or graphs) because captions can contain a lot more information. Alt text is usually brief.

Vignette about multi-scale analyses

I think that's the most common complaint about SFE in papers about data analysis methods that cited my paper. I have long had that idea but didn't get the chance to implement it yet. Can be spatial binning SERaster style, or creating a series of spatial neighborhood graphs with different distance cutoffs and see how that affects the results.

Joint count vignette

Looks like people really like cell types, so would be nice to have a categorical method.

error in `geom_spi_rgb()` when using ` image_id` in `plotSpatialFeature()`

imgData(sfe)
DataFrame with 5 rows and 4 columns
     sample_id    image_id   data scaleFactor
   <character> <character> <list>   <numeric>
1 test.merfish  Cellbound1   ####           1
2 test.merfish  Cellbound2   ####           1
3 test.merfish  Cellbound3   ####           1
4 test.merfish        DAPI   ####           1
5 test.merfish       PolyT   ####           1

options(repr.plot.height = 5, repr.plot.width = 10)
pl1 <- 
plotSpatialFeature(sfe, features = "sum", 
                   size = 4, colGeometryName = "cellSeg", 
                   scattermore = TRUE, # will plot only centroids!
                   image_id = "DAPI" # 
                  ) & DarkTheme()
pl1

scattermore and binning only apply to points. Using centroids.
ERROR while rich displaying an object: Error in `geom_spi_rgb()`:
! Problem while converting geom to grob.
Error occurred in the 1st layer.
Caused by error in `rgb()`:
! color intensity 47180, not in 0:255

This error happen when using image_id. Something to do with max_col_value in Voyager:::geom_spi_rgb(., max_col_value = 255)
any suggestions?
Thanks

Error when bbox is used

Error for plotSpatialFeature:

Error in (function (msg) : TopologyException: unable to assign free hole to a shell at 5376.6752999999999 -2471.8000000000002
Traceback:

1. plotSpatialFeature(sfe, features = rownames(sfe)[1], bbox = bbox_use, 
 .     size = 4, colGeometryName = "cell", dark = TRUE, image_id = imgData(sfe)$image_id[1], 
 .     )
2. .plotSpatialFeature(sfe, values, colGeometryName, sample_id, 
 .     ncol, ncol_sample, annotGeometryName, annot_aes, annot_fixed, 
 .     bbox, image_id, aes_use, divergent, diverge_center, annot_divergent, 
 .     annot_diverge_center, size, shape, linewidth, linetype, alpha, 
 .     color, fill, scattermore, pointsize, bins, summary_fun, hex, 
 .     maxcell, dark, ...)
3. .crop(df, bbox)
4. .bbox_sample(df, bbox)
5. suppressWarnings(df <- st_intersection(df, bbox_use))
6. withCallingHandlers(expr, warning = function(w) if (inherits(w, 
 .     classes)) tryInvokeRestart("muffleWarning"))
7. st_intersection(df, bbox_use)
8. st_intersection.sf(df, bbox_use)
9. geos_op2_df(x, y, geos_op2_geom("intersection", x, y, ...))
10. geos_op2_geom("intersection", x, y, ...)
11. st_sfc(CPL_geos_op2(op, x, y), crs = st_crs(x))
12. CPL_geos_op2(op, x, y)
13. (function (msg) 
  . {
  .     on.exit(stop(msg))
  .     lst = strsplit(msg, " at ")[[1]]
  .     pts = scan(text = lst[[length(lst)]], quiet = TRUE)
  .     if (length(pts) == 2 && is.numeric(pts)) 
  .         assign(".geos_error", st_point(pts), envir = .sf_cache)
  . })("TopologyException: unable to assign free hole to a shell at 5376.6752999999999 -2471.8000000000002")
14. stop(msg)

and related error in SFE for crop

Error in scan(text = lst[[length(lst)]], quiet = TRUE): scan() expected 'a real', got '-1677.7229097180282.'
Traceback:

1. SpatialFeatureExperiment::crop(sfe, colGeometryName = "cell", 
 .     sample_id = "test_xenium", y = bbox_use)
2. lapply(colGeometries(out), .crop_geometry, y = y, samples_use = samples_use, 
 .     op = op, id_col = "barcode", sample_col = colData(out)$sample_id)
3. FUN(X[[i]], ...)
4. lapply(names(gs), function(s) {
 .     if (s %in% samples_use) {
 .         if ("sample_id" %in% names(y)) {
 .             y_use <- st_geometry(y[y$sample_id == s, ])
 .         }
 .         else {
 .             y_use <- st_geometry(y)
 .         }
 .         .g <- gs[[s]][, c("geometry", id_col)]
 .         st_agr(.g) <- "constant"
 .         o <- op(.g, y_use)
 .         if (is(o, "sgbp")) {
 .             inds <- lengths(o) > 0L
 .             return(gs[[s]][inds, ])
 .         }
 .         else {
 .             if (any(!rownames(o) %in% rownames(.g))) {
 .                 o <- aggregate(o, by = setNames(list(id = o[[id_col]]), 
 .                   id_col), FUN = unique)
 .             }
 .             return(merge(o, st_drop_geometry(gs[[s]]), by = id_col, 
 .                 all = TRUE))
 .         }
 .     }
 .     else {
 .         return(gs[[s]])
 .     }
 . })
5. FUN(X[[i]], ...)
6. op(.g, y_use)
7. st_intersection.sf(.g, y_use)
8. geos_op2_df(x, y, geos_op2_geom("intersection", x, y, ...))
9. geos_op2_geom("intersection", x, y, ...)
10. st_sfc(CPL_geos_op2(op, x, y), crs = st_crs(x))
11. CPL_geos_op2(op, x, y)
12. (function (msg) 
  . {
  .     on.exit(stop(msg))
  .     lst = strsplit(msg, " at ")[[1]]
  .     pts = scan(text = lst[[length(lst)]], quiet = TRUE)
  .     if (length(pts) == 2 && is.numeric(pts)) 
  .         assign(".geos_error", st_point(pts), envir = .sf_cache)
  . })("TopologyException: side location conflict at 1870.8501000000001 -1677.7229097180282. This can occur if the input geometry is invalid.")
13. scan(text = lst[[length(lst)]], quiet = TRUE)

Refactor `SFEMethods` to be more like `BlusParam`

This will significantly change the SFEMethods S4 class. This will make Voyager more consistent with other Bioconductor packages that provide uniform user interfaces to multiple methods to achieve the same goal, such as BiocParallel, BiocSingular, and bluster. Hopefully this can also make it easier to extend Voyager.

Matrix >= 1.6.2 breaks Voyager

In running reverse dependency checks for spdep, I see a failure: function as_cholmod_sparse not provided by package 'Matrix' not caused by changes in spdep.

Voyager utility

thank you for creating this amazing tool - is it fair to assume that voyager is a replacement for analysis for spatial data like seurat/giotto. seems like there is a lot of inconsistencies with all the different package analyses out there.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.