The following is an example of usage of the widget in a Shiny app.
First, install the dependencies:
install.packages("shiny") install.packages("devtools") devtools::install_github("satijalab/seurat-data") devtools::install_github("vitessce/vitessceAnalysisR")
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.
library(shiny) library(vitessceR) library(vitessceAnalysisR) library(SeuratData) SeuratData::InstallData("pbmc3k") data("pbmc3k.final") force(pbmc3k.final) adata_path <- file.path("data", "seurat", "pbmc3k.final.h5ad.zarr") vitessceAnalysisR::seurat_to_anndata_zarr(pbmc3k.final, adata_path) w <- AnnDataWrapper$new( adata_path=adata_path, obs_embedding_paths = c("obsm/X_pca", "obsm/X_umap"), obs_embedding_names = c("PCA", "UMAP"), obs_set_paths = c("obs/seurat_annotations", "obs/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(schema_version = "1.0.16", name = "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(theme="light") }) } 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.
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 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:
library(shiny) library(vitessceR) library(SeuratData) SeuratData::InstallData("pbmc3k") data("pbmc3k.final") force(pbmc3k.final) BASE_DIR <- file.path("data", "seurat") adata_filename <- "pbmc3k.final.h5ad.zarr" vitessceAnalysisR::seurat_to_anndata_zarr(pbmc3k.final, file.path(BASE_DIR, adata_filename)) w <- AnnDataWrapper$new( adata_path=adata_filename, obs_embedding_paths = c("obsm/X_pca", "obsm/X_umap"), obs_embedding_names = c("PCA", "UMAP"), obs_set_paths = c("obs/seurat_annotations", "obs/seurat_clusters") ) ui <- fluidPage( "Vitessce in a Shiny app", vitessce_output(output_id = "vitessce_visualization", height = "600px"), ) server <- function(input, output, session) { # Ask Shiny to also serve our data files in our local ./data/seurat folder from "/vitessce" addResourcePath("vitessce", BASE_DIR) # Render the Vitessce widget into the UI output. output$vitessce_visualization <- render_vitessce(expr = { # Tell Vitessce that file paths (in AnnDataWrapper) are relative to the BASE_DIR folder. vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config", base_dir = BASE_DIR) dataset <- vc$add_dataset("My dataset") dataset <- dataset$add_object(w) scatterplot <- vc$add_view(dataset, Component$SCATTERPLOT, mapping = "PCA") vc$layout(scatterplot) # Construct a base_url value dynamically based on the Shiny session info. BASE_URL <- paste0( session$clientData$url_protocol, "//", session$clientData$url_hostname, ":", session$clientData$url_port, session$clientData$url_pathname, "vitessce" ) vc$widget(theme = "light", serve = FALSE, base_url = BASE_URL) }) } shinyApp(ui, server)
Listen for input$vitessce_on_config_change
events emitted by the Vitessce widget in order to observe user interactions and update the Shiny app in response.
library(shiny) library(vitessceR) library(vitessceAnalysisR) library(SeuratData) SeuratData::InstallData("pbmc3k") data("pbmc3k.final") force(pbmc3k.final) adata_path <- file.path("data", "seurat", "pbmc3k.final.h5ad.zarr") vitessceAnalysisR::seurat_to_anndata_zarr(pbmc3k.final, adata_path) w <- AnnDataWrapper$new( adata_path=adata_path, obs_embedding_paths = c("obsm/X_pca", "obsm/X_umap"), obs_embedding_names = c("PCA", "UMAP"), obs_set_paths = c("obs/seurat_annotations", "obs/seurat_clusters") ) ui <- fluidPage( "Vitessce in a Shiny app", vitessce_output(output_id = "vitessce_visualization", height = "600px"), verbatimTextOutput("vitessce_config") ) server <- function(input, output, session) { output$vitessce_visualization <- render_vitessce(expr = { vc <- VitessceConfig$new(schema_version = "1.0.16", name = "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(theme="light") }) rv <- reactiveValues(current=NULL) observeEvent(input$vitessce_on_config_change, { # We can access any values from the coordination space here. # In this example, we access the ID of the currently-hovered cell. rv$current <- input$vitessce_on_config_change[['coordinationSpace']][['obsHighlight']] }) output$vitessce_config <- renderPrint({ rv$current }) } shinyApp(ui, server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.