diff --git a/DESCRIPTION b/DESCRIPTION index f79523b..2fab100 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,20 +29,13 @@ VignetteBuilder: knitr Imports: Matrix, DelayedArray, - htmlwidgets, jsonlite, - R6, - plumber, - future, - httpuv, - stringr, reticulate, varhandle, tools, stats, methods, S4Vectors, - grDevices, basilisk, zellkonverter, SummarizedExperiment, diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index df8817f..e668f5e 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -19,13 +19,6 @@ navbar: examples: text: Examples menu: - - text: "Examples with Remote Data" - - text: "Usage with OME-TIFF: Remote Example" - href: articles/web_only/ome_tiff_remote.html - - text: "Usage with JSON: Remote Example" - href: articles/web_only/json_remote.html - - text: ------- - - text: "Examples with Local Data" - text: "Overview: Using the widget with local data" href: articles/local_data_overview.html - text: "Usage with SeuratData" @@ -38,18 +31,6 @@ navbar: href: articles/single_cell_experiment.html - text: "Usage with SpatialExperiment" href: articles/spatial_experiment.html - - text: "Usage with OME-TIFF: Local Example" - href: articles/ome_tiff_local.html - - text: "Usage with JSON: Local Example" - href: articles/json_local.html - - text: ------- - - text: "Other Examples" - - text: "Usage with Shiny" - href: articles/shiny.html - - text: "Usage with pkgdown" - href: articles/pkgdown.html - - text: "Export data to static files" - href: articles/export_files.html core_docs: text: "Core Docs" href: http://vitessce.io/docs/ diff --git a/vignettes/debugging.Rmd b/vignettes/debugging.Rmd deleted file mode 100644 index 817e347..0000000 --- a/vignettes/debugging.Rmd +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: "Debugging" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Debugging} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -When working with the `vitessceR` package, you may encounter issues, particularly related to file formatting, file permissions, URL typos, etc. Below, we list some debugging methods that may help to resolve these bugs. - -If none of these tips help, please write an issue on [GitHub](https://github.com/vitessce/vitessceR/issues). - -The following code snippets assume that `vitessceR` has been loaded via `library(vitessceR)` and the Vitessce configuration instance is stored in the variable `vc`: - - -```r -library(vitessceR) -vc <- VitessceConfig$new("My single-cell data visualization") -``` - -## Use the `out_dir` parameter for data object wrapper classes - -Rather than using a temporary directory, this will write converted files to the specified directory. -This way, you can open and explore the converted output files. - -```r -dir.create("./debug") - -dataset <- vc$add_dataset("My dataset") -dataset <- dataset$add_object(SeuratWrapper$new(pbmc3k.final, out_dir = "./debug")) -``` - -## Use the `port` parameter - -```r -vc$widget(port = 9000) -``` - -## Add the `status` component to the layout - -```r -status <- vc$add_view(dataset, Component$STATUS) -vc$layout(hconcat(scatterplot, status)) -``` - -## Write the configuration to JSON - -```r -vc_list <- vc$to_list() -jsonlite::toJSON(vc_list, auto_unbox = TRUE) -``` - -## Open the browser console - -If the Vitessce widget loads in the RStudio "Viewer" tab, but the data fails to load or there are issues related to the user interface, you can open the browser console to check for errors or warning messages. - -To do so, right click in the Viewer area and select "Inspect Element." - -Then, click "Console" in the inspector window that appears. - diff --git a/vignettes/dev_wrapper_class.Rmd b/vignettes/dev_wrapper_class.Rmd deleted file mode 100644 index 5b42590..0000000 --- a/vignettes/dev_wrapper_class.Rmd +++ /dev/null @@ -1,208 +0,0 @@ ---- -title: "Developer guide: Writing a data wrapper class" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Developer guide: Writing a data wrapper class} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -The following is a guide for development of wrapper classes for single-cell data structures. -For this guide, we will focus on writing a wrapper class for Seurat objects which supports the `cells`, `cell-sets`, and `expression-matrix` Vitessce data types. - -To begin, we can write a skeleton for the class, which contains functions that we will fill in. -Here, we start by overriding the `convert_and_save` function of the parent `AbstractWrapper` class. - -The `initialize` constructor function takes the parameter `obj` which will be the Seurat of interest (i.e., the object that we are wrapping). - -The `convert_and_save` function performs any required data conversion steps, creates the web server routes, and creates the corresponding file definition creator functions. - -Complete file definitions cannot be finalized at this stage because the file definitions depend on the `base_url` (the URL on which the files will ultimately be served, typically "http://localhost:8000"). - -```r -SeuratWrapper <- R6::R6Class("SeuratWrapper", - inherit = AbstractWrapper, - public = list( - obj = NULL, - initialize = function(obj, ...) { - super$initialize(...) - self$obj <- obj - }, - convert_and_save = function(dataset_uid, obj_i) { - super$convert_and_save(dataset_uid, obj_i) - # TODO - } - ) -) -``` - -## Cells - -We can begin to create the output files and web server route details for the `cells` data type. -Files with the `cells` data type can contain cell-level observations, such as dimensionality reduction coordinates for each cell. - -For now, we can create a new function called `create_cells_list` which we will fill in later. - -The `make_cells_file_def_creator` is a function which creates and returns a new "file definition creator" function. -All file definition creator functions must take the `base_url` parameter and return a complete file definition. -File definitions should be lists with named values: - -- `type`: a Vitessce data type string (for convenience, the values in the `DataType` list can be used), -- `fileType`: a Vitessce file type string (for convenience, the values in the `FileType` list can be used), -- `url`: a URL string (required for most file types, but optional for the `raster.json` file type), -- `options`: optional list of extra options (not necessary for any JSON file types). - -In `convert_and_save` we append the new file definition creator to the list `self$file_def_creators` and we append a new web server route to `self$routes`. - -```r -SeuratWrapper <- R6::R6Class("SeuratWrapper", - inherit = AbstractWrapper, - public = list( - obj = NULL, - initialize = function(obj, ...) { - super$initialize(...) - self$obj <- obj - }, - create_cells_list = function() { - # TODO - }, - make_cells_file_def_creator = function(dataset_uid, obj_i) { - get_cells <- function(base_url) { - file_def <- list( - type = DataType$CELLS, - fileType = FileType$CELLS_JSON, - url = super$get_url(base_url, dataset_uid, obj_i, "cells.json") - ) - return(file_def) - } - return(get_cells) - }, - convert_and_save = function(dataset_uid, obj_i) { - super$convert_and_save(dataset_uid, obj_i) - - # Get list representations of the data. - cells_list <- self$create_cells_list() - - # Convert the lists to JSON strings. - cells_json <- jsonlite::toJSON(cells_list) - - # Save the JSON strings to JSON files. - write(cells_json, file = self$get_out_dir(dataset_uid, obj_i, "cells.json")) - - # Get the file definition creator functions. - cells_file_creator <- self$make_cells_file_def_creator(dataset_uid, obj_i) - - # Append the new file definition creator function to the main list. - self$file_def_creators <- append(self$file_def_creators, cells_file_creator) - - # Append a new web server route object which corresponds to the directory of JSON files to be served. - self$routes <- append(self$routes, self$get_out_dir_route(dataset_uid, obj_i)) - } - ) -) -``` - -Next, we want to fill in the `create_cells_list` function. -This function should return an R list which will be automatically converted to a JSON object by [jsonlite](https://cran.r-project.org/web/packages/jsonlite/vignettes/json-aaquickstart.html). - -For reference: - -- [`cells.json` schema](https://github.com/vitessce/vitessce/blob/master/src/schemas/cells.schema.json) -- [`cells.json` small example](https://github.com/vitessce/vitessce/blob/master/src/schemas/fixtures/cells.good.json) -- [`cells.json` full example](https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/dries/dries.cells.json) - -We know that we need to obtain the following from the Seurat object: - -- a unique ID for each cell, and -- an (x, y) scatterplot coordinate representing the first two dimensions of a dimensionality reduction for each cell. - -When we inspect a Seurat object in the R environment, we can see that it has the type `S4 object of class Seurat`. - -To access the values in an S4 object, we can use `slot(obj, "key")` where `"key"` is replaced by the key for the part of the object that we want to access. - -Inspecting the object further, we can see that: - -- dimensionality reductions are stored under the key `"reductions"` -- cell barcodes are stored under the key `"active.ident"` - -To generalize our function, we can get a list of names of each dimensionality reduction available with `names(slot(obj, "reductions"))`. - -We can get a list of cell IDs with `names(slot(obj, "active.ident"))`. - -Then we can iterate over the cell IDs and set up a new empty object with `obj_list()`. -Note [`obj_list()`](https://github.com/vitessce/vitessce-r/blob/8d4d7f9/R/helpers.R#L35) returns an empty R list that is always translated to a JSON object (rather than the base R `list()` which is translated to a JSON _array_ when empty). - -Then we can iterate over each available dimensionality reduction and cell. -We obtain the cell's (x,y) coordinates with `embedding_matrix[cell_id, 1:2]` where `embedding_matrix` is the dimensionality reduction matrix. -For example, if the dimensionality reduction is `"pca"` then the matrix can be accessed at `slot(slot(obj, "reductions")[["pca"]], "cell.embeddings")`. - -Finally, we return the R list we created. - -```r -SeuratWrapper <- R6::R6Class("SeuratWrapper", - inherit = AbstractWrapper, - public = list( - obj = NULL, - initialize = function(obj, ...) { - super$initialize(...) - self$obj <- obj - }, - create_cells_list = function() { - obj <- self$obj - embeddings <- slot(obj, "reductions") - available_embeddings <- names(embeddings) - - cell_ids <- names(slot(obj, "active.ident")) - cells_list <- obj_list() - for(cell_id in cell_ids) { - cells_list[[cell_id]] <- list( - mappings = obj_list() - ) - } - for(embedding_name in available_embeddings) { - embedding <- embeddings[[embedding_name]] - embedding_matrix <- slot(embedding, "cell.embeddings") - for(cell_id in cell_ids) { - cells_list[[cell_id]]$mappings[[embedding_name]] <- unname(embedding_matrix[cell_id, 1:2]) - } - } - - return(cells_list) - }, - make_cells_file_def_creator = function(dataset_uid, obj_i) { - get_cells <- function(base_url) { - file_def <- list( - type = DataType$CELLS, - fileType = FileType$CELLS_JSON, - url = super$get_url(base_url, dataset_uid, obj_i, "cells.json") - ) - return(file_def) - } - return(get_cells) - }, - convert_and_save = function(dataset_uid, obj_i) { - super$convert_and_save(dataset_uid, obj_i) - - # Get list representations of the data. - cells_list <- self$create_cells_list() - - # Convert the lists to JSON strings. - cells_json <- jsonlite::toJSON(cells_list) - - # Save the JSON strings to JSON files. - write(cells_json, file = self$get_out_dir(dataset_uid, obj_i, "cells.json")) - - # Get the file definition creator functions. - cells_file_creator <- self$make_cells_file_def_creator(dataset_uid, obj_i) - - # Append the new file definition creator function to the main list. - self$file_def_creators <- append(self$file_def_creators, cells_file_creator) - - # Append a new web server route object which corresponds to the directory of JSON files to be served. - self$routes <- append(self$routes, self$get_out_dir_route(dataset_uid, obj_i)) - } - ) -) -``` - - diff --git a/vignettes/dev_wrapper_subclass.Rmd b/vignettes/dev_wrapper_subclass.Rmd deleted file mode 100644 index fd40cb3..0000000 --- a/vignettes/dev_wrapper_subclass.Rmd +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: "Developer guide: Extending a data wrapper class" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Developer guide: Extending a data wrapper class} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -The existing data object wrapper classes are not yet very flexible, but they can be extended to support custom use cases. - -Here, we extend the `SeuratWrapper` class so that it supports multiple cell sets, to deal with the fact that the Seurat [`FindClusters`](https://satijalab.org/seurat/reference/findclusters) overwrites its results each time. - -```r -library(vitessceR) - -#' Subclass of SeuratWrapper to deal with cell sets. -#' @title MyCustomSeuratWrapper Class -#' @docType class -#' @description -#' Subclass of SeuratWrapper. -MyCustomSeuratWrapper <- R6::R6Class("MyCustomSeuratWrapper", - inherit = SeuratWrapper, - public = list( - #' @field cell_sets The cell sets. - #' @keywords internal - cell_sets = NULL, - #' @description - #' Create a wrapper around a Seurat object. - #' @param obj The object to wrap. - #' @param cell_sets A list of cell sets. - #' @param ... Parameters inherited from `SeuratWrapper`. - #' @return A new `SeuratWrapper` object. - initialize = function(obj, cell_sets, ...) { - super$initialize(obj, ...) - self$cell_sets <- cell_sets - }, - #' @description - #' Create a list representing the cluster assignments in the cell set list. - #' @return A list that can be converted to JSON. - #' @keywords internal - create_cell_sets_list = function() { - obj <- self$obj - - cells <- Seurat::Idents(obj) - - # https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.cell-sets.json - cell_sets_list <- list( - datatype = jsonlite::unbox("cell"), - version = jsonlite::unbox("0.1.3"), - tree = list() - ) - - if(!is.na(self$cell_sets)) { - for(cell_set_name in names(self$cell_sets)) { - cell_set <- self$cell_sets[[cell_set_name]] - - cell_set_meta_node <- list( - name = jsonlite::unbox(cell_set_name), - children = list() - ) - cell_set_annotations <- cell_set - cell_set_annotation_scores <- NA - - cluster_names <- sort(unique(cell_set_annotations)) - - for(cluster_name in cluster_names) { - cells_in_cluster <- names(cells[cell_set_annotations == cluster_name]) - - # TODO: find out if there is a way to return NULL - make_null_tuples <- function(x) { list(jsonlite::unbox(x), jsonlite::unbox(NA)) } - cells_in_cluster_with_score <- purrr::map(cells_in_cluster, make_null_tuples) - - cluster_node <- list( - name = jsonlite::unbox(cluster_name), - set = cells_in_cluster_with_score - ) - cell_set_meta_node$children <- append(cell_set_meta_node$children, list(cluster_node)) - } - cell_sets_list$tree <- append(cell_sets_list$tree, list(cell_set_meta_node)) - } - } - cell_sets_list - } - ) -) -``` - -Next, we can preprocess the dataset. -```r -library(Seurat) - -# Download example dataset -url <- "https://cf.10xgenomics.com/samples/cell/pbmc3k/pbmc3k_filtered_gene_bc_matrices.tar.gz" -dir.create("seurat") -download.file(url, destfile = "seurat/filtered_gene_bc_matrices.tar.gz") -untar("seurat/filtered_gene_bc_matrices.tar.gz", exdir = "seurat") - -# Load example dataset -pbmc.data <- Read10X(data.dir = "seurat/filtered_gene_bc_matrices/hg19") - -# Process example dataset (run PCA and cluster) -pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200) -pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-") -pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5) -pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000) -pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000) -all.genes <- rownames(pbmc) -pbmc <- ScaleData(pbmc, features = all.genes) -pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc)) -pbmc <- FindNeighbors(pbmc, dims = 1:10) -``` - -We can run `FindClusters` with different algorithms and save the clustering results to new variables between each algorithm, since the results in the Seurat object will be overwritten each time. - -```r -louvain_clusters <- slot(FindClusters(pbmc, algorithm = 1, resolution = 0.3), "meta.data")$seurat_clusters -slm_clusters <- slot(FindClusters(pbmc, algorithm = 3), "meta.data")$seurat_clusters -cell_sets_list <- list(louvain = louvain_clusters, SLM = slm_clusters) -``` - -With this list of cell sets, we can now create an instance of our custom SeuratWrapper subclass: - -```r -my_wrapped_object <- MyCustomSeuratWrapper$new(pbmc, cell_sets = cell_sets_list, out_dir = "out") -``` - -Now, we create the Vitessce config as usual: -```r -# Create Vitessce view config -vc <- VitessceConfig$new("My config") -dataset <- vc$add_dataset("My dataset")$add_object(my_wrapped_object) -scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "pca") -status <- vc$add_view(dataset, Component$STATUS) -desc <- vc$add_view(dataset, Component$DESCRIPTION) -desc <- desc$set_props(description = "Visualization of a Seurat object containing the PBMC 3K dataset.") -cell_sets <- vc$add_view(dataset, Component$CELL_SETS) -vc$layout(hconcat( - vconcat(scatterplot), - vconcat(cell_sets, vconcat(desc, status)) -)) -# Render the Vitessce widget -vc$widget(theme = "light") -``` diff --git a/vignettes/export_files.Rmd b/vignettes/export_files.Rmd deleted file mode 100644 index 53c8bfe..0000000 --- a/vignettes/export_files.Rmd +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Export data to static files" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Export data to static files} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -After configuring a Vitessce widget, you may want to obtain the static files associated and deploy the same Vitessce configuration as a static website. -This page demonstrates this process for an example dataset from [SeuratData](https://github.com/satijalab/seurat-data). - -First, install the dependencies: - -```r -install.packages("devtools") -devtools::install_github("satijalab/seurat-data") -``` - -Create the Vitessce configuration: - -```r -library(vitessceR) -library(SeuratData) - -SeuratData::InstallData("pbmc3k") -data("pbmc3k.final") -force(pbmc3k.final) - -vc <- VitessceConfig$new("My config") -dataset <- vc$add_dataset("My dataset") -dataset <- dataset$add_object( - SeuratWrapper$new( - pbmc3k.final, - cell_embeddings = c("pca", "umap"), - cell_embedding_names = c("PCA", "UMAP"), - cell_set_meta_names = c("seurat_annotations", "seurat_clusters"), - out_dir = file.path("data", "seuratdata") - ) -) -scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") -vc$layout(scatterplot) -``` - -# Export files for serving locally - -Run the `export` function on the `VitessceConfig`. -Specify the directory in which to store the exported files with `out_dir`. - -```r -vc$export(out_dir = "./my_vitessce_files") -``` - -The directory `./my_vitessce_files` should now contain three files: - -- `cells.json` -- `cell-sets.json` -- `clusters.json` - -## Serve the exported files - -Now that the files have been saved to the `./my_vitessce_files` directory, they can be served by any static web server. - -If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew: - -```sh -http-server ./my_vitessce_files/ --cors -p 3000 -``` - -## View on vitessce.io - -The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues. - -```r -vc_list <- vc$to_list(base_url = "http://localhost:3000") -vitessce_url <- paste0("http://vitessce.io/?url=data:,", URLencode(jsonlite::toJSON(vc_list, auto_unbox = TRUE))) -print(vitessce_url) -``` - -# Export files for serving from AWS S3 - -Rather than serving the data files locally, you may want to upload the files to a remote static file hosting service such as AWS S3, allowing the Vitessce URL to be shared with others. -Visit our [data hosting](http://beta.vitessce.io/docs/data-hosting/index.html) documentation page to learn more about configuring file hosting services for use with Vitessce. -Install the AWS S3 command-line interface by following the instructions [here](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html). - -Confirm that the CLI has been installed: - -```sh -aws --version -``` - -Configure the AWS CLI by using any of the configuration methods, such as the [environment variable method](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html). - - -In the case of AWS S3, you know ahead of time that the data files will ultimately be served from your S3 bucket, so you can include the `base_url` and `with_config = TRUE` parameters when calling the export function. -For instance, if you intend to upload the files to an AWS S3 bucket called `my_bucket`: - -```r -vc$export(with_config = TRUE, base_url = "https://my_bucket.s3.amazonaws.com", out_dir = "./my_vitessce_files") -``` - -The directory `./my_vitessce_files` should now contain the three data files, plus the view config as a JSON file (`config.json`): - -- `cells.json` -- `cell-sets.json` -- `clusters.json` -- `config.json` (the file URLs in this config will include the `base_url` for the bucket) - -## Upload exported files to S3 - -Upload all four files to your bucket: - -```sh -aws s3 cp --recursive ./my_vitessce_files s3://my_bucket -``` - -In this case, rather than including the configuration as url-encoded JSON in the URL, you can simply point to the configuration JSON file in the bucket: - -`http://vitessce.io/?url=https://my_bucket.s3.amazonaws.com/config.json` - diff --git a/vignettes/json_local.Rmd b/vignettes/json_local.Rmd deleted file mode 100644 index 4f1c217..0000000 --- a/vignettes/json_local.Rmd +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "Usage with JSON: Local Example" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Usage with JSON: Local Example} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -The following is an example of usage of the widget with JSON files. In this example, the JSON files are stored locally. - -## Setup - -In this tutorial, we will serve the JSON files using a local web server. - -Any static web server will work, and an easy one to install and configure is [http-server](https://github.com/http-party/http-server#readme). - - -## Download the data - -First, download the files used in this example: - -- https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.cells.json -- https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.cell-sets.json -- https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.molecules.json -- https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.clusters.json -- https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/linnarsson.raster.json - -## Serve the JSON files locally - -To serve the downloaded JSON files, move them to a new folder (for instance `vitessce_json_example` in the `Downloads` folder). Using the terminal, change directories to this folder containing the JSON files. - -```sh -cd ~/Downloads/vitessce_json_example/ -``` - -Serve the contents of this directory (the JSON files) using `http-server`: - -```sh -http-server ./ --cors -p 8000 -``` - -## Configure the Vitessce widget - -Add JSON files to the dataset using the `add_file` function. The `add_file` function returns the updated dataset, allowing the function calls to be chained. - -```r -library(vitessceR) - -base_url <- "http://localhost:8000/" - -# Create Vitessce view config -vc <- VitessceConfig$new("Codeluppi et al., Nature Methods 2018") -dataset <- vc$add_dataset("Codeluppi")$add_file( - url = paste0(base_url, "linnarsson.cells.json"), - data_type = DataType$CELLS, - file_type = FileType$CELLS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.cell-sets.json"), - data_type = DataType$CELL_SETS, - file_type = FileType$CELL_SETS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.molecules.json"), - data_type = DataType$MOLECULES, - file_type = FileType$MOLECULES_JSON -)$add_file( - url = paste0(base_url, "linnarsson.clusters.json"), - data_type = DataType$EXPRESSION_MATRIX, - file_type = FileType$CLUSTERS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.raster.json"), - data_type = DataType$RASTER, - file_type = FileType$RASTER_JSON -) - -desc <- vc$add_view(dataset, Component$DESCRIPTION) -desc <- desc$set_props(description = "Codeluppi et al., Nature Methods 2018: Spatial organization of the somatosensory cortex revealed by osmFISH.") - -spatial <- vc$add_view(dataset, Component$SPATIAL) -spatial_layers <- vc$add_view(dataset, Component$LAYER_CONTROLLER) - -scatterplot_pca <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") -scatterplot_tsne <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "t-SNE") -status <- vc$add_view(dataset, Component$STATUS) - -cell_sets <- vc$add_view(dataset, Component$CELL_SETS) -gene_list <- vc$add_view(dataset, Component$GENES) -heatmap <- vc$add_view(dataset, Component$HEATMAP)$set_props(transpose = TRUE) - -vc$layout(hconcat( - vconcat(vconcat(desc, status), spatial_layers), - vconcat(heatmap, spatial), - vconcat(scatterplot_tsne, scatterplot_pca), - vconcat(gene_list, cell_sets) -)) - -# Render the Vitessce widget -vc$widget(theme = "light") -``` - - - diff --git a/vignettes/ome_tiff_local.Rmd b/vignettes/ome_tiff_local.Rmd deleted file mode 100644 index 5a3de6a..0000000 --- a/vignettes/ome_tiff_local.Rmd +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Usage with OME-TIFF: Local Example" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Usage with OME-TIFF: Local Example} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -The following is an example of usage of the widget to visualize a local OME-TIFF image file. - -Configure the Vitessce widget: - -```r -library(vitessceR) - -# Create Vitessce view config -vc <- VitessceConfig$new("My config") -dataset <- vc$add_dataset("My dataset")$add_object( - MultiImageWrapper$new( - image_wrappers = list( - OmeTiffWrapper$new(name="Test", img_path="/Users/mkeller/Downloads/exemplar-001.pyramid.ome.tif") - ) - ) -) -spatial <- vc$add_view(dataset, Component$SPATIAL) -spatial_layers <- vc$add_view(dataset, Component$LAYER_CONTROLLER) -status <- vc$add_view(dataset, Component$STATUS) -desc <- vc$add_view(dataset, Component$DESCRIPTION) -desc <- desc$set_props(description = "Visualization of an OME-TIFF file.") -vc$layout(hconcat( - spatial, - hconcat(spatial_layers, vconcat(desc, status)) -)) - -# Render the Vitessce widget -vc$widget(theme = "light") -``` - - - diff --git a/vignettes/pkgdown.Rmd b/vignettes/pkgdown.Rmd deleted file mode 100644 index 5ec139f..0000000 --- a/vignettes/pkgdown.Rmd +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Usage with pkgdown" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Usage with pkgdown} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r setup, include = FALSE} -chunk <- "```" -``` - -[Pkgdown](https://pkgdown.r-lib.org/) is an R package designed to build documentation websites for R packages. -However, it can also be an easy way to create a static website using R. - -The Vitessce widget can be embedded in a static website built with pkgdown. In fact, this documentation website was built with pkgdown, and both of the remote data examples ([Usage with JSON: Remote Example](./web_only/json_remote.html) and [Usage with OME-TIFF: Remote Example](./web_only/ome_tiff_remote.html)) take advantage of the ability to render R htmlwidgets into a pkgdown website. - -To render a Vitessce widget into a pkgdown article, set the [chunk options](https://r4ds.had.co.nz/r-markdown.html#chunk-options) at the top of the code block such that output is rendered, and execute the widget function in the final line of the code block. - - `r chunk`{r echo = TRUE} - library(vitessceR) - - vc <- VitessceConfig$new("My config") - - # configure vitessce here - - vc$widget(theme = "light", width = "100%") - `r chunk` - -Note that because `pkgdown` sites are static, pkgdown cannot be used to serve data to Vitessce, so only remote datasets (with files added via the [dataset$add_file](../reference/VitessceConfigDataset.html#method-add_file) method) can be used on pkgdown sites. - -The full code for the two examples linked above can be explored on GitHub: - -* https://github.com/vitessce/vitessceR/blob/main/vignettes/web_only/json_remote.Rmd -* https://github.com/vitessce/vitessceR/blob/main/vignettes/web_only/ome_tiff_remote.Rmd -* Pkgdown configuration files: https://github.com/vitessce/vitessceR/tree/main/pkgdown -* GitHub Actions deployment script: https://github.com/vitessce/vitessceR/blob/main/.github/workflows/deploy.yml#L30 - diff --git a/vignettes/shiny.Rmd b/vignettes/shiny.Rmd deleted file mode 100644 index a3fc550..0000000 --- a/vignettes/shiny.Rmd +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: "Usage with Shiny" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Usage with Shiny} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -The following is an example of usage of the widget in a [Shiny](https://shiny.rstudio.com/) app. - -First, install the dependencies: -```r -install.packages("shiny") -install.packages("devtools") -devtools::install_github("satijalab/seurat-data") -``` - -Next, create an output element in the UI with `vitessce_output` and a corresponding server response with `render_vitessce`. - -The value for the `output_id` parameter in the `vitessce_output` function should match the key for the result of `render_vitessce` in the server. - -```r -library(shiny) -library(vitessceR) -library(SeuratData) - -SeuratData::InstallData("pbmc3k") -data("pbmc3k.final") -force(pbmc3k.final) - -w <- SeuratWrapper$new( - pbmc3k.final, - cell_embeddings = c("pca", "umap"), - cell_embedding_names = c("PCA", "UMAP"), - cell_set_metas = c("seurat_annotations", "seurat_clusters") -) - -ui <- fluidPage( - "Vitessce in a Shiny app", - vitessce_output(output_id = "vitessce_visualization", height = "600px"), -) - -server <- function(input, output, session) { - output$vitessce_visualization <- render_vitessce(expr = { - vc <- VitessceConfig$new("My config") - dataset <- vc$add_dataset("My dataset") - dataset <- dataset$add_object(w) - scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") - vc$layout(scatterplot) - vc$widget() - }) -} - -shinyApp(ui, server) -``` - -When running the Shiny app, the Vitessce widget will take a few seconds to appear on the screen. -We plan to optimize the internal widget data preparation and conversion functions to reduce this delay. - -## Shiny apps on remote servers - -When running a Shiny app on a remote server, you will need to use the `base_url` parameter of the `vc$widget()` function. -When a value for `base_url` is provided, the default `http://localhost` base URL will be overridden, allowing the client of the Shiny app to be running on a different computer than the Shiny server. - -You also may want to serve the Vitessce widget data files through a custom static web server rather than the built-in R [plumber](https://www.rplumber.io/) web server (either for security or scalability reasons). -To do so, be sure to set the parameter `out_dir` when calling the `SeuratWrapper$new()` constructor. This will allow you to specify the output directory for the converted Vitessce data files. -Then, you can set the parameter `serve` to `FALSE` in `vc$widget()` to prevent the built-in plumber server from starting when you launch the widget. - -For example, if you know that your Shiny server will be running at `http://example.com/shiny` and you want to turn off the plumber server, then you would call `vc$widget(base_url = "http://example.com/shiny", serve = FALSE)`. - -The following example demonstrates swapping out the Vitessce widget's built-in server for Shiny's [addResourcePath](https://shiny.rstudio.com/reference/shiny/1.0.2/addResourcePath.html): - -```r -library(shiny) -library(vitessceR) -library(SeuratData) - -SeuratData::InstallData("pbmc3k") -data("pbmc3k.final") -force(pbmc3k.final) - -OUT_DIR <- file.path("data", "shiny") - -w <- SeuratWrapper$new( - pbmc3k.final, - cell_embeddings = c("pca", "umap"), - cell_embedding_names = c("PCA", "UMAP"), - cell_set_metas = c("seurat_annotations", "seurat_clusters"), - out_dir = OUT_DIR -) - -ui <- fluidPage( - "Vitessce in a Shiny app", - vitessce_output(output_id = "vitessce_visualization", height = "600px"), -) - -server <- function(input, output, session) { - addResourcePath("vitessce", OUT_DIR) - output$vitessce_visualization <- render_vitessce(expr = { - vc <- VitessceConfig$new("My config") - dataset <- vc$add_dataset("My dataset") - dataset <- dataset$add_object(w) - scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") - vc$layout(scatterplot) - - BASE_URL <- paste0( - session$clientData$url_protocol, - "//", - session$clientData$url_hostname, - ":", - session$clientData$url_port, - "/vitessce" - ) - - vc$widget(serve = FALSE, base_url = BASE_URL) - }) -} - -shinyApp(ui, server) -``` - -## Style issues - -By default, Shiny includes CSS from bootstrap in all apps. -The bootstrap styles (font sizes in particular) can interfere with the styles for the Vitessce widget. - -One solution is add CSS to reset the font sizes for the root element of the Shiny app: - -```r -library(shiny) -library(vitessceR) -library(SeuratData) - -SeuratData::InstallData("pbmc3k") -data("pbmc3k.final") -force(pbmc3k.final) - -w <- SeuratWrapper$new( - pbmc3k.final, - cell_embeddings = c("pca", "umap"), - cell_embedding_names = c("PCA", "UMAP"), - cell_set_metas = c("seurat_annotations", "seurat_clusters") -) - -ui <- fluidPage( - tags$head( - tags$style(HTML(" - html, body { - font-size: inherit; - } - ")) - ), - "Vitessce in a Shiny app", - vitessce_output(output_id = "vitessce_visualization", height = "600px"), -) - -server <- function(input, output, session) { - output$vitessce_visualization <- render_vitessce(expr = { - vc <- VitessceConfig$new("My config") - dataset <- vc$add_dataset("My dataset") - dataset <- dataset$add_object(w) - scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") - vc$layout(scatterplot) - vc$widget() - }) -} - -shinyApp(ui, server) -``` - - diff --git a/vignettes/web_only/json_remote.Rmd b/vignettes/web_only/json_remote.Rmd deleted file mode 100644 index d294a81..0000000 --- a/vignettes/web_only/json_remote.Rmd +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "Usage with JSON: Remote Example" -output: rmarkdown::html_vignette -package: vitessce -vignette: > - %\VignetteIndexEntry{Usage with JSON: Remote Example} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, setup, include=FALSE} -knitr::opts_knit$set( - root.dir = dirname(dirname(getwd())), - rmarkdown.pandoc.to = knitr::opts_knit$get("rmarkdown.pandoc.to") -) -``` - -The following is an example of usage of the widget with JSON files. In this example, the JSON files are stored on a remote AWS S3 bucket. For information about remote file hosting, please visit the [Hosting Data](http://vitessce.io/docs/data-hosting/) page of the main Vitessce documentation website. - -## Configure the Vitessce widget - -Add JSON files to the dataset using the `add_file` function. The `add_file` function returns the updated dataset, allowing the function calls to be chained. - -```{r echo = TRUE, warning = FALSE} -library(vitessceR) - -base_url <- "https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/linnarsson/" - -# Create Vitessce view config -vc <- VitessceConfig$new("Codeluppi et al., Nature Methods 2018") -dataset <- vc$add_dataset("Codeluppi")$add_file( - url = paste0(base_url, "linnarsson.cells.json"), - data_type = DataType$CELLS, - file_type = FileType$CELLS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.cell-sets.json"), - data_type = DataType$CELL_SETS, - file_type = FileType$CELL_SETS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.molecules.json"), - data_type = DataType$MOLECULES, - file_type = FileType$MOLECULES_JSON -)$add_file( - url = paste0(base_url, "linnarsson.clusters.json"), - data_type = DataType$EXPRESSION_MATRIX, - file_type = FileType$CLUSTERS_JSON -)$add_file( - url = paste0(base_url, "linnarsson.raster.json"), - data_type = DataType$RASTER, - file_type = FileType$RASTER_JSON -) - -desc <- vc$add_view(dataset, Component$DESCRIPTION) -desc <- desc$set_props(description = "Codeluppi et al., Nature Methods 2018: Spatial organization of the somatosensory cortex revealed by osmFISH.") - -spatial <- vc$add_view(dataset, Component$SPATIAL) -spatial_layers <- vc$add_view(dataset, Component$LAYER_CONTROLLER) - -scatterplot_pca <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") -scatterplot_tsne <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "t-SNE") -status <- vc$add_view(dataset, Component$STATUS) - -cell_sets <- vc$add_view(dataset, Component$CELL_SETS) -gene_list <- vc$add_view(dataset, Component$GENES) -heatmap <- vc$add_view(dataset, Component$HEATMAP)$set_props(transpose = TRUE) - -vc$layout(hconcat( - vconcat(vconcat(desc, status), spatial_layers), - vconcat(heatmap, spatial), - vconcat(scatterplot_tsne, scatterplot_pca), - vconcat(gene_list, cell_sets) -)) -``` - -```{r eval = FALSE, echo = TRUE} -# Render the Vitessce widget -vc$widget(theme = "light", width = "100%") -``` - -```{r eval = TRUE, echo = FALSE} -if(!is.null(knitr::opts_knit$get("rmarkdown.pandoc.to")) && knitr::opts_knit$get("rmarkdown.pandoc.to") == "html") { - vc$widget(theme = "light", width = "100%") -} -``` - - - diff --git a/vignettes/web_only/ome_tiff_remote.Rmd b/vignettes/web_only/ome_tiff_remote.Rmd deleted file mode 100644 index 2fc3c60..0000000 --- a/vignettes/web_only/ome_tiff_remote.Rmd +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Usage with OME-TIFF: Remote Example" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Usage with OME-TIFF: Remote Example} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, setup, include=FALSE} -knitr::opts_knit$set( - root.dir = dirname(dirname(getwd())), - rmarkdown.pandoc.to = knitr::opts_knit$get("rmarkdown.pandoc.to") -) -``` - -The following is an example of usage of the widget to visualize a remote OME-TIFF image file. - -First, configure the Vitessce widget: - -```{r echo = TRUE, warning = FALSE} -library(vitessceR) - -# Define the image file options object. -file_options = obj_list( - schemaVersion = "0.0.2", - images = list( - obj_list( - name = "My Image", - type = "ome-tiff", - url = "https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif" - ) - ), - renderLayers = list( - "My Image" - ) -) - -# Create Vitessce view config -vc <- VitessceConfig$new("My config") -dataset <- vc$add_dataset("My dataset")$add_file( - data_type = DataType$RASTER, - file_type = FileType$RASTER_JSON, - options = file_options -) -spatial <- vc$add_view(dataset, Component$SPATIAL) -spatial_layers <- vc$add_view(dataset, Component$LAYER_CONTROLLER) -status <- vc$add_view(dataset, Component$STATUS) -desc <- vc$add_view(dataset, Component$DESCRIPTION) -desc <- desc$set_props(description = "Visualization of an OME-TIFF file.") -vc$layout(hconcat( - spatial, - hconcat(spatial_layers, vconcat(desc, status)) -)) -``` - -```{r eval = FALSE, echo = TRUE} -# Render the Vitessce widget -vc$widget(theme = "light", width = "100%") -``` - -```{r eval = TRUE, echo = FALSE} -if(!is.null(knitr::opts_knit$get("rmarkdown.pandoc.to")) && knitr::opts_knit$get("rmarkdown.pandoc.to") == "html") { - vc$widget(theme = "light", width = "100%") -} -``` - - - -