Spaces:
Sleeping
Sleeping
title: "SPIDER-web" | |
author: "Cao Lab" | |
server: shiny | |
format: | |
dashboard: | |
logo: https://ZhengTiger.github.io/picx-images-hosting/PFCapp/Logo-circle.7sn4nqapcl.png | |
nav-buttons: | |
- icon: github | |
href: https://github.com/ZhengTiger/SPIDER-Seq | |
# Home | |
<p style="font-size: 50px; font-weight: bold; text-align: center;">Modular organization of mouse prefrontal cortex subnetwork revealed by spatial single-cell multi-omic analysis of SPIDER-Seq</p> | |
<br> | |
<img src="https://ZhengTiger.github.io/picx-images-hosting/PFCapp/Figure1A.2doqkri93w.webp" style="width: 100%;"> | |
<br> | |
<br> | |
<p style="font-size: 30px; font-weight: bold; text-align: left;"> | |
Summary | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
Deciphering the connectome, transcriptome and spatial-omics integrated multi-modal brain atlas and the underlying organization principles remains a great challenge. We developed a cost-effective Single-cell Projectome-transcriptome In situ Deciphering Sequencing (SPIDER-Seq) technique by combining viral barcoding tracing with single-cell sequencing and spatial-omics. This empowers us to delineate a comprehensive integrated single-cell spatial molecular, cellular and projectomic atlas of mouse prefrontal cortex (PFC). The projectomic and transcriptomic cell clusters display distinct modular organization principles, but are coordinately configured in the PFC. The projection neurons gradiently occupied different territories in the PFC aligning with their wiring patterns. Importantly, they show higher co-projection probability to the downstream nuclei with reciprocal circuit connections. Moreover, we integrated projectomic atlas with their distinct spectrum of neurotransmitter/neuropeptide and the receptors-related gene profiles and depicted PFC neural signal transmission network. By which, we uncovered potential mechanisms underlying the complexity and specificity of neural transmission. Finally, we predicted neuron projections with high accuracy by combining gene profiles and spatial information via machine learning. This study facilitates our understanding of brain multi-modal network and neural computation. | |
</p> | |
<br> | |
<p style="font-size: 30px; font-weight: bold; text-align: left;"> | |
Interactively exploring our data | |
</p> | |
<p style="font-size: 20px; font-weight: bold; text-align: left;"> | |
scRNAseq | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
Our scRNAseq dataset sequenced the PFC of 3 mice. It contains the transcriptome of mouse PFC and the projectome information of 24 PFC targets. Users can browse the following content through the scRNAseq page: | |
</p> | |
- scRNAseq Clustering: Select different resolutions to view cell clusters on UMAP | |
- Gene Expression: Select different genes to view their expression on UMAP | |
- Barcode Expression: Select different projections to view their expression on UMAP | |
- Barcode Cell Numbers: View PFC projection cell numbers in different cell clusters | |
<p style="font-size: 20px; font-weight: bold; text-align: left;"> | |
Spatial data | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
Our spatial dataset sequenced 36 slices of mouse PFC. It contains 32 genes and 15 targets information of mouse PFC. Users can browse the following content through the spatial page: | |
</p> | |
- Spatial Clustering: Select different resolutions to view the spatial distribution of cell clusters | |
- Spatial Gene Expression: Select different genes to view their spatial expression | |
- Spatial Barcode Expression: Select different projections to view their spatial expression | |
- Barcode Spatial Distribution: View the spatial distribution of PFC projection neurons along anterior-posterior and ventralis-dorsalis axes | |
<p style="font-size: 20px; font-weight: bold; text-align: left;"> | |
3D | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
3D interactive visualization of mouse PFC. Users can browse the following content through the 3D page: | |
</p> | |
- Transcriptome 3D Visualization: Select different transcriptome cell clusters to interactively view them in 3D | |
- Projectome 3D Visualization: Select different Projectome targets to interactively view them in 3D | |
<p style="font-size: 20px; font-weight: bold; text-align: left;"> | |
Download | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
Download the raw and processed data from this study. | |
</p> | |
```{r} | |
#| context: setup | |
#| warning: false | |
#| message: false | |
library(ggplot2) | |
library(Seurat) | |
library(shiny) | |
library(rgl) | |
library(ggdark) | |
library(viridis) | |
library(dplyr) | |
source("R/Palettes.R") | |
source('R/includes.R') | |
Adult.Ex <- readRDS('data/Adult.Ex.rds') | |
sp.PFC <- readRDS('data/sp.PFC.rds') | |
sp.PFC$PTi[is.na(sp.PFC$PTi)] <- 0 | |
sp.PFC$ITi_D[is.na(sp.PFC$ITi_D)] <- 0 | |
sp.PFC$ITi_V[is.na(sp.PFC$ITi_V)] <- 0 | |
sp.PFC$ITc[is.na(sp.PFC$ITc)] <- 0 | |
sp.PFC$Proj_module[which(sp.PFC$Proj_module=="ITi-D")] <- "ITi-M1" | |
sp.PFC$Proj_module[which(sp.PFC$Proj_module=="ITi-V")] <- "ITi-M2" | |
sp.PFC$Proj_module[which(sp.PFC$Proj_module=="ITc")] <- "ITc-M3" | |
colnames([email protected])[match(c("ITi_D","ITi_V","ITc"),colnames([email protected]))] <- c("ITi-M1","ITi-M2","ITc-M3") | |
clean_cells <- colnames(Adult.Ex)[!( | |
(Adult.Ex$Ex_subtype %in% c("CT","NP") & Adult.Ex$BC_num>0) | | |
(Adult.Ex$sample %in% c("Adult2","Adult3") & Adult.Ex$Ex_subtype=="PT" & Adult.Ex$BC_num>0) | |
)] | |
Adult.Ex.clean <- subset(Adult.Ex, cells = clean_cells) | |
Adult.Ex.clean$Proj_module[which(Adult.Ex.clean$Proj_module=="ITi-D")] <- "ITi-M1" | |
Adult.Ex.clean$Proj_module[which(Adult.Ex.clean$Proj_module=="ITi-V")] <- "ITi-M2" | |
Adult.Ex.clean$Proj_module[which(Adult.Ex.clean$Proj_module=="ITc")] <- "ITc-M3" | |
colnames([email protected])[match(c("ITi_D_score", "ITi_V_score", "ITc_score", "PTi_score"),colnames([email protected]))] <- c("ITi-M1", "ITi-M2","ITc-M3","PTi") | |
options(rgl.useNULL = TRUE) | |
``` | |
# scRNAseq {scrolling="true"} | |
## {.sidebar} | |
```{r} | |
selectInput('cluster', 'Select Cluster', c("SubType_Layer","SubType")) | |
``` | |
```{r} | |
selectInput('gene', 'Select Gene', rownames(Adult.Ex), | |
selected = "Cux2") | |
``` | |
```{r} | |
Barcode <- c( | |
"ITi-M1", "ITi-M2", "ITc-M3", "PTi", | |
'VIS-I','SSp-I','CP-I','AUD-I','RSP-I', | |
'BLA-I','ACB-I','ENTl-I','AId-I','ECT-I', | |
'ACB-C','PL-C','ECT-C','ENTl-C', | |
'BLA-C','CP-C','AId-C','RSP-C', | |
'MD-I','RE-I','DR-I','VTA-I','LHA-I','SC-I') | |
selectInput('target', 'Select Target', Barcode, selected = "CP-I") | |
``` | |
## Column | |
### Row | |
#### Column | |
```{r} | |
plotOutput('cluster_plot') | |
``` | |
#### Column | |
```{r} | |
plotOutput('gene_plot') | |
``` | |
### Row | |
#### Column | |
```{r} | |
plotOutput('target_plot') | |
``` | |
#### Column | |
```{r} | |
plotOutput('target_bar_plot') | |
``` | |
```{r} | |
#| context: server | |
output$cluster_plot <- renderPlot({ | |
DimPlot( | |
Adult.Ex, | |
reduction = 'umap', | |
group.by = input$cluster, | |
cols = col_cluster[[input$cluster]], | |
label = T | |
) + | |
coord_fixed() | |
}) | |
output$gene_plot <- renderPlot({ | |
FeaturePlot( | |
Adult.Ex, | |
features = input$gene) + | |
coord_fixed() | |
}) | |
output$target_plot <- renderPlot({ | |
Barcode <- c( | |
"ITi-M1", "ITi-M2","ITc-M3","PTi", | |
'VIS-I','SSp-I','CP-I','AUD-I','RSP-I', | |
'BLA-I','ACB-I','ENTl-I','AId-I','ECT-I', | |
'ACB-C','PL-C','ECT-C','ENTl-C', | |
'BLA-C','CP-C','AId-C','RSP-C', | |
'MD-I','RE-I','DR-I','VTA-I','LHA-I','SC-I' | |
) | |
seu <- Adult.Ex.clean | |
[email protected][,Barcode][is.na([email protected][,Barcode])] <- 0 | |
FeaturePlot( | |
seu, features = input$target, order = T) + | |
coord_fixed() | |
}) | |
output$target_bar_plot <- renderPlot({ | |
seu <- Adult.Ex.clean | |
if (input$target %in% c("ITi-M1", "ITi-M2","ITc-M3","PTi")){ | |
df <- as.data.frame(table([email protected][,input$cluster][which(seu$Proj_module==input$target)])) | |
}else{ | |
df <- as.data.frame(table([email protected][,input$cluster][which([email protected][,input$target]>0)])) | |
} | |
colnames(df) <- c("Celltypes","Cellnum") | |
ggplot(df, aes(x=Celltypes, y=Cellnum, fill=Celltypes)) + | |
geom_col() + | |
scale_fill_manual(values = col_cluster[[input$cluster]]) + | |
theme_classic() + | |
theme(axis.text.x = element_text(angle = 25, hjust = 1), | |
plot.title = element_text(hjust = 0.5)) + | |
labs(title = paste("PFC → ",input$target," cell numbers in different cell type", | |
sep="")) | |
}) | |
``` | |
# Spatial {scrolling="true"} | |
## {.sidebar} | |
```{r} | |
selectInput('sp_slice', 'Select Slice', unique(sp.PFC$slice), | |
selected = "IT_slice_10") | |
``` | |
```{r} | |
selectInput('sp_cluster', 'Select Cluster', c("SubType_Layer","SubType")) | |
``` | |
```{r} | |
selectInput('sp_gene', 'Select Gene', rownames(sp.PFC), | |
selected = "Cux2") | |
``` | |
```{r} | |
sp_Barcode <- c( | |
"ITi-M1", "ITi-M2","ITc-M3","PTi", | |
'VIS-I','SSp-I','CP-I','AUD-I','RSP-I', | |
'BLA-I','ACB-I','AId-I','ECT-I', | |
'ACB-C','ECT-C','CP-C','AId-C','RSP-C', | |
'LHA-I') | |
selectInput('sp_target', 'Select Target', sp_Barcode) | |
``` | |
## Column | |
### Row | |
#### Column | |
```{r} | |
#| fig-width: 10 | |
plotOutput('sp_cluster_plot') | |
``` | |
#### Column | |
```{r} | |
#| fig-width: 10 | |
plotOutput('sp_gene_plot') | |
``` | |
### Row | |
#### Column | |
```{r} | |
#| fig-width: 10 | |
plotOutput('sp_target_plot') | |
``` | |
#### Column | |
```{r} | |
#| fig-width: 10 | |
plotOutput('sp_target_line_plot') | |
``` | |
```{r} | |
#| context: server | |
output$sp_cluster_plot <- renderPlot({ | |
df <- data.frame( | |
x = sp.PFC$ML_new[sp.PFC$slice==input$sp_slice], | |
y = sp.PFC$DV_new[sp.PFC$slice==input$sp_slice], | |
type = [email protected][sp.PFC$slice==input$sp_slice, input$sp_cluster] | |
) | |
ggplot(df, aes(x=x, y=y, color=type)) + | |
geom_point(size=1) + | |
scale_color_manual(values = col_cluster[[input$sp_cluster]]) + | |
labs(title = paste(input$slice,'Cell types in spatial')) + | |
guides(color=guide_legend(nrow = 2, byrow = TRUE, reverse = T, | |
override.aes = list(size=2))) + | |
coord_fixed() + | |
ggdark::dark_theme_void() + | |
theme(plot.title = element_text(size = 20, hjust = 0.5), | |
legend.position = 'bottom', legend.title=element_blank(), | |
legend.text = element_text(size=10)) | |
}) | |
output$sp_gene_plot <- renderPlot({ | |
df <- data.frame( | |
X = sp.PFC$ML_new, | |
Y = sp.PFC$DV_new, | |
Zscore = scale(log1p(sp.PFC@assays$RNA@counts[input$sp_gene,])) | |
) | |
df <- df[which(sp.PFC$slice==input$sp_slice),] | |
df$Zscore[df$Zscore<0] <- 0 | |
df$Zscore[df$Zscore>3] <- 3 | |
df <- df[order(df$Zscore),] | |
ggplot(df,aes(x=X,y=Y)) + | |
geom_point(aes(colour=Zscore), size=1) + | |
scale_color_gradientn(colours = viridis(n = 256, option = "D", direction = 1), | |
limits = c(0,3)) + | |
ggdark::dark_theme_void() + | |
labs(title = input$sp_gene) + | |
theme(plot.title = element_text(size = 20, hjust = 0.5), | |
legend.position = 'bottom') + | |
coord_fixed() | |
}) | |
output$sp_target_plot <- renderPlot({ | |
df <- data.frame( | |
X = sp.PFC$ML_new, | |
Y = sp.PFC$DV_new, | |
Zscore = scale(log1p([email protected][,input$sp_target])) | |
) | |
df <- df[which(sp.PFC$slice==input$sp_slice),] | |
df$Zscore[df$Zscore<0] <- 0 | |
df$Zscore[df$Zscore>3] <- 3 | |
df <- df[order(df$Zscore),] | |
ggplot(df, aes(x=X,y=Y)) + | |
geom_point(aes(colour=Zscore), size=1) + | |
scale_color_gradientn(colours = viridis(n = 256, option = "E", direction = 1)) + | |
ggdark::dark_theme_void() + | |
labs(title = input$sp_target) + | |
theme(plot.title = element_text(size = 20, hjust = 0.5), | |
legend.position = 'bottom') + | |
coord_fixed() | |
}) | |
output$sp_target_line_plot <- renderPlot({ | |
# AP | |
seu <- subset(sp.PFC, cells=colnames(sp.PFC)[which(sp.PFC$ABA_hemisphere=="Left")]) | |
slice <- unique(seu$slice) | |
df <- data.frame('slice'=slice) | |
for (i in 1:length(slice)){ | |
if (input$sp_target %in% c("ITi-M1","ITi-M2","ITc-M3","PTi")){ | |
df$cellnum[i] <- length(which(seu$slice==slice[i] & seu$Proj_module==input$sp_target))/length(which(seu$slice==slice[i] & seu$BC_num>0)) | |
}else{ | |
df$cellnum[i] <- length(which(seu$slice==slice[i] & [email protected][,input$sp_target]>0))/length(which(seu$slice==slice[i] & seu$BC_num>0)) | |
} | |
} | |
df$x <- c(1:36) | |
p1 <- ggplot(df, aes(x=x, y=cellnum)) + | |
geom_point(alpha=0.5, size=3, color=col_subtype_target[input$sp_target]) + | |
geom_smooth(se = F, linewidth=1.5, color=col_subtype_target[input$sp_target]) + | |
theme_bw() + | |
scale_x_continuous(breaks = seq(0,35,5)) + | |
theme(text = element_text(size=15), | |
plot.title = element_text(size = 20, hjust = 0.5)) + | |
labs(x='A → P',y='Cell proportion') | |
# DV | |
sp_Barcode <- c("ITi-M1","ITi-M2","ITc-M3", "PTi", | |
'VIS-I','SSp-I','CP-I','AUD-I','RSP-I', | |
'BLA-I','ACB-I','AId-I','ECT-I', | |
'ACB-C','ECT-C','CP-C','AId-C','RSP-C', | |
'LHA-I') | |
seu <- subset(sp.PFC, cells=colnames(sp.PFC)[which(sp.PFC$ABA_hemisphere=="Left")]) | |
bc_slice <- [email protected][,c(sp_Barcode, 'Y','BC_num')] | |
bc_slice <- | |
bc_slice |> | |
mutate(bin = cut(Y, breaks = 36)) | |
bin <- sort(unique(bc_slice$bin)) | |
bc_slice$bin_index <- match(bc_slice$bin, bin) | |
df <- data.frame('bin_index'=c(1:36)) | |
for (i in 1:36){ | |
df$cellnum[i] <- length(which(bc_slice$bin_index==i & | |
bc_slice[,input$sp_target]>0))/ | |
length(which(bc_slice$bin_index==i & bc_slice$BC_num>0)) | |
} | |
df$x <- c(1:36) | |
p2 <- ggplot(df, aes(x=x, y=cellnum)) + | |
geom_point(alpha=0.5, size=3, color=col_subtype_target[input$sp_target]) + | |
geom_smooth(se = F, linewidth=1.5, color=col_subtype_target[input$sp_target]) + | |
theme_bw() + | |
scale_x_continuous(breaks = seq(0,35,5)) + | |
theme(text = element_text(size=15), | |
plot.title = element_text(size = 20, hjust = 0.5)) + | |
labs(x='V → D',y='Cell proportion') | |
p1/p2 | |
}) | |
``` | |
# 3D | |
## {.sidebar} | |
```{r} | |
sp_Barcode <- c("ITi-M1","ITi-M2","ITc-M3", "PTi", | |
'VIS-I','SSp-I','CP-I','AUD-I','RSP-I', | |
'BLA-I','ACB-I','AId-I','ECT-I', | |
'ACB-C','ECT-C','CP-C','AId-C','RSP-C', | |
'LHA-I') | |
waiter::use_waiter() | |
selectInput('subtype_3d', 'Select SubType', sort(unique(sp.PFC$SubType))) | |
selectInput('target_3d', 'Select Target', sp_Barcode, selected = "PTi") | |
``` | |
## Column | |
```{r} | |
rglwidgetOutput('spatial_subtype', width = "100%") | |
``` | |
```{r} | |
#| context: server | |
observeEvent(input$subtype_3d,{ | |
waiter::Waiter$new(id = "spatial_subtype", color="black")$show() | |
output$spatial_subtype <- renderRglwidget({ | |
df_plot <- [email protected][which(sp.PFC$SubType == input$subtype_3d),] | |
open3d() | |
bg3d(color = "black") | |
par3d(userMatrix = rotationMatrix(-pi/6, -1, 1, 0), zoom = 0.6) | |
acr.list <- c("MOs","PL","ORBm","ACAd","ILA","DP","ACAv") | |
for(acr in acr.list){ | |
mesh <- mesh3d.allen.annot.from.id(get.id.from.acronym(acr)) | |
col <- "lightgray" | |
shade3d(mesh, col = col, material = list(lit=FALSE), alpha = 0.1) | |
} | |
spheres3d(x = df_plot$ML_new, | |
y = df_plot$DV_new, | |
z = df_plot$AP_new, | |
col = col_subtype_target[input$subtype_3d], radius=0.01, alpha=1) | |
rglwidget() | |
}) | |
}) | |
observeEvent(input$target_3d,{ | |
waiter::Waiter$new(id = "spatial_subtype", color="black")$show() | |
output$spatial_subtype <- renderRglwidget({ | |
if (input$target_3d %in% c("ITi-M1","ITi-M2","ITc-M3", "PTi")){ | |
df_plot <- [email protected][which(sp.PFC$Proj_module==input$target_3d),] | |
}else{ | |
df_plot <- [email protected][which([email protected][,input$target_3d] > 0),] | |
} | |
open3d() | |
bg3d(color = "black") | |
par3d(userMatrix = rotationMatrix(-pi/6, -1, 1, 0), zoom = 0.6) | |
acr.list <- c("MOs","PL","ORBm","ACAd","ILA","DP","ACAv") | |
for(acr in acr.list){ | |
mesh <- mesh3d.allen.annot.from.id(get.id.from.acronym(acr)) | |
col <- "lightgray" | |
shade3d(mesh, col = col, material = list(lit=FALSE), alpha = 0.1) | |
} | |
spheres3d(x = df_plot$ML_new, | |
y = df_plot$DV_new, | |
z = df_plot$AP_new, | |
col = col_subtype_target[input$target_3d], radius=0.01, alpha=1) | |
rglwidget() | |
}) | |
}) | |
``` | |
# Download | |
<p style="font-size: 20px; text-align: justify;"> | |
The raw single cell RNA-seq data are available from GEO (<a href="https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE273066">GSE273066</a>). | |
</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
The raw image data for this study are available via Hugging Face at <a href="https://huggingface.co/TigerZheng/SPIDER-STdata">TigerZheng/SPIDER-STdata</a>. You can download and unzip the .zip file and then use <a href="https://github.com/hms-dbmi/viv">viv</a> to visualize our raw data. | |
An example: <a href="https://avivator.gehlenborglab.org/?image_url=https://huggingface.co/TigerZheng/SPIDER-STdata/resolve/main/IT_slice_36_reordered.ome.tiff">IT_slice_36</a>.</p> | |
<p style="font-size: 20px; text-align: justify;"> | |
The processed data can be downloaded here:</p> | |
- All cells data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/all.Adult.rds?download=true">all.Adult.rds</a> | |
- Excitatory data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/Adult.Ex.rds?download=true">Adult.Ex.rds</a> | |
- Spatial data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/sp.PFC.rds?download=true">sp.PFC.rds</a> | |