-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathshiny.Rmd
188 lines (147 loc) · 6.61 KB
/
shiny.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
---
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")
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.
```r
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.
## 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)
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,
"/vitessce"
)
vc$widget(theme = "light", serve = FALSE, base_url = BASE_URL)
})
}
shinyApp(ui, server)
```
## Bidirectional communication example
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.
```r
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)
```