Stickels, R.R., Murray, E., Kumar, P., Li, J., Marshall, J.L., Di Bella, D.J., Arlotta, P., Macosko, E.Z., and Chen, F. (2020). Highly sensitive spatial transcriptomics at near-cellular resolution with Slide-seqV2. Nat. Biotechnol.
Load required packages.
library(data.table)
library(tidyverse)
library(magrittr)
library(patchwork)
library(extrafont)
library(Matrix)Sys.time()## [1] "2021-02-06 18:19:50 CST"
source(
file = file.path(
SCRIPT_DIR,
"utilities.R"
)
)PROJECT_DIR <- "/Users/jialei/Dropbox/Data/Projects/UTSW/Spatial_sequencing/datasets/Slide-seqV2"list.files(path = file.path(PROJECT_DIR, "raw/SCP815/other"))## [1] "Puck_190921_19_bead_locations.csv.gz"
## [2] "Puck_190921_19.digital_expression.txt.gz"
## [3] "Puck_190921_21_bead_locations.csv.gz"
## [4] "Puck_190921_21.digital_expression.txt.gz"
## [5] "Puck_190926_01_bead_locations.csv.gz"
## [6] "Puck_190926_01.digital_expression.txt.gz"
## [7] "Puck_190926_02_bead_locations.csv.gz"
## [8] "Puck_190926_02.digital_expression.txt.gz"
## [9] "Puck_190926_03_bead_locations.csv.gz"
## [10] "Puck_190926_03.digital_expression.txt.gz"
## [11] "Puck_190926_06_bead_locations.csv.gz"
## [12] "Puck_190926_06.digital_expression.txt.gz"
## [13] "Puck_191007_07_bead_locations.csv.gz"
## [14] "Puck_191007_07.digital_expression.txt.gz"
## [15] "Puck_191204_01_bead_locations.csv.gz"
## [16] "Puck_191204_01.digital_expression.txt.gz"
## [17] "Puck_200115_08_bead_locations.csv.gz"
## [18] "Puck_200115_08.digital_expression.txt.gz"
Load matrix and coordinates.
matrix_readcount_use <- load_matrix(
x = file.path(
PROJECT_DIR,
"raw/SCP815/other",
"Puck_200115_08.digital_expression.txt.gz"
)
)
barcode_location <- read_csv(
file = file.path(
PROJECT_DIR,
"raw/SCP815/other",
"Puck_200115_08_bead_locations.csv.gz"
),
col_names = c("barcode", "x_coord", "y_coord"),
skip = 1
)##
## ── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## cols(
## barcode = col_character(),
## x_coord = col_double(),
## y_coord = col_double()
## )
Create AnnData object.
ad <- reticulate::import(module = "anndata", convert = TRUE)
print(ad$`__version__`)## [1] "0.7.5"
adata <- ad$AnnData(
X = t(matrix_readcount_use),
obs = data.frame(
cell = colnames(matrix_readcount_use),
num_umis = colSums(matrix_readcount_use),
mt_percentage = colSums(
matrix_readcount_use[
str_detect(
string = rownames(matrix_readcount_use),
pattern = "mt-"
),
]
) / colSums(matrix_readcount_use),
row.names = colnames(matrix_readcount_use)
),
var = data.frame(
feature = rownames(matrix_readcount_use),
row.names = rownames(matrix_readcount_use)
)
)
file_name <- file.path(
PROJECT_DIR,
"clustering",
"matrices",
"puck_200115_08.h5ad"
)
# file_name
if (!file.exists(file_name)) {
adata$write(
file_name
)
}barcode_location %<>%
mutate(
num_umis = colSums(matrix_readcount_use[, barcode]),
num_features = colSums(matrix_readcount_use[, barcode] > 0),
num_umis_mt = colSums(
matrix_readcount_use[
str_detect(string = rownames(matrix_readcount_use), pattern = "mt-"),
barcode
]
),
mt_ratio = num_umis_mt / num_umis
)
barcode_location %>%
summarise(
num_cells = n(),
median_umis = median(num_umis),
median_features = median(num_features),
median_mt_ratio = median(mt_ratio)
) %>%
gt::gt() %>%
# gt::cols_label(n = "num_cells") %>%
gt::tab_options(table.font.size = "median")| num_cells | median_umis | median_features | median_mt_ratio |
|---|---|---|---|
| 53208 | 302 | 235 | 0.08514392 |
purrr::map(seq(0, 1, 0.25), function(x) {
cat(x, "\n")
barcode_location %>%
summarise(
num_umis = quantile(num_umis, x),
num_features = quantile(num_features, x),
mt_ratio = quantile(mt_ratio, x)
) %>%
mutate(
quantile = x
) %>%
select(quantile, everything())
}) %>%
bind_rows() %>%
gt::gt() %>%
# gt::cols_label(n = "num_cells") %>%
gt::tab_options(table.font.size = "median")## 0
## 0.25
## 0.5
## 0.75
## 1
| quantile | num_umis | num_features | mt_ratio |
|---|---|---|---|
| 0.00 | 10.00 | 6 | 0.00000000 |
| 0.25 | 118.00 | 98 | 0.04605263 |
| 0.50 | 302.00 | 235 | 0.08514392 |
| 0.75 | 736.25 | 553 | 0.15544586 |
| 1.00 | 23772.00 | 8557 | 0.68421053 |
GEOM_POINT_SIZE <- 0.5
p_spatial_UMI <- plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = barcode_location$num_umis %>% log10(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
ggplot2::guides(
color = ggplot2::guide_colourbar(
title = expression(paste("Log"[10], " (UMIs)"))
)
) +
scale_color_gradientn(
colors = colorRampPalette(
colors = rev(
x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
)
)(n = 100)
)## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
p_spatial_features <- plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = barcode_location$num_features %>% log10(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
ggplot2::guides(
color = ggplot2::guide_colourbar(
title = expression(paste("Log"[10], " (Genes)"))
)
) +
scale_color_gradientn(
colors = colorRampPalette(
colors = rev(
x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
)
)(n = 100)
)## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
Fig. 1a
GEOM_POINT_SIZE <- 0.5
purrr::map2(
c("num_umis", "num_features"),
c(
expression(paste("Log"[10], " (UMIs)")),
expression(paste("Log"[10], " (Genes)"))
), function(x, y) {
plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = barcode_location[[x]] %>% log10(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
ggplot2::guides(
color = ggplot2::guide_colourbar(
title = y
)
) +
scale_color_gradientn(
colors = colorRampPalette(
colors = rev(
x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
)
)(n = 100)
)
}
) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(
ncol = 2
) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = barcode_location$mt_ratio,
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
ggplot2::guides(
color = ggplot2::guide_colourbar(
title = "MT %"
)
) +
scale_color_gradientn(
colors = colorRampPalette(
colors = rev(
x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
)
)(n = 100)
)## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
Visualize cells with different numbers of genes detected.
GEOM_POINT_SIZE <- 0.3
purrr::map(c(200, 500, 1000, 2000), function(x) {
plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = as.numeric(barcode_location$num_features >= x) %>%
as.factor(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
scale_color_manual(
values = c("grey70", "salmon"),
labels = paste(c("<", ">="), x)
)
}) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(
ncol = 2
) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)Fig. 1c
purrr::map(c("Gapdh", "Atp2b1", "Ociad2", "Slc17a7"), function(x) {
plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = log10(matrix_readcount_use[x, barcode_location$barcode] + 1),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
ggplot2::guides(
color = ggplot2::guide_colourbar(
title = x
)
) +
scale_color_gradientn(
colors = colorRampPalette(
colors = rev(
x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
)
)(n = 100)
)
}) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(
ncol = 2
) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
## Scale for 'colour' is already present. Adding another scale for 'colour',
## which will replace the existing scale.
embedding <- read_csv(
file = file.path(
PROJECT_DIR,
"clustering/puck_200115_08/exploring",
"embedding_ncomponents32_ccc1_seed20200416.csv.gz"
)
)##
## ── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## cols(
## cell = col_character(),
## batch = col_logical(),
## louvain = col_double(),
## leiden = col_double(),
## x_tsne = col_double(),
## y_tsne = col_double(),
## x_umap = col_double(),
## y_umap = col_double(),
## x_fitsne = col_double(),
## y_fitsne = col_double(),
## x_phate = col_double(),
## y_phate = col_double(),
## `x_umap_min_dist=0.1` = col_double(),
## `y_umap_min_dist=0.1` = col_double(),
## x_multicoretsne = col_double(),
## y_multicoretsne = col_double()
## )
embedding %>% dim()## [1] 27680 16
embedding %<>%
mutate(
num_umis = colSums(matrix_readcount_use[, cell]),
num_features = colSums(matrix_readcount_use[, cell] > 0),
mt_ratio = colSums(
matrix_readcount_use[
str_detect(string = rownames(matrix_readcount_use), pattern = "mt-"),
cell
]
) / num_umis
)
embedding %>% head()embedding %>%
dplyr::group_by(leiden) %>%
dplyr::summarise(
num_cells = n(),
median_umis = median(num_umis),
median_features = median(num_features),
median_mt_ratio = median(mt_ratio)
) %>%
gt::gt() %>%
gt::tab_options(table.font.size = "median")| leiden | num_cells | median_umis | median_features | median_mt_ratio |
|---|---|---|---|---|
| 0 | 3791 | 979.0 | 737.0 | 0.04683728 |
| 1 | 3268 | 587.0 | 426.0 | 0.05598757 |
| 2 | 3205 | 451.0 | 351.0 | 0.09631148 |
| 3 | 2822 | 382.0 | 302.0 | 0.10734285 |
| 4 | 2074 | 1183.0 | 866.5 | 0.04478874 |
| 5 | 1729 | 968.0 | 724.0 | 0.03016241 |
| 6 | 1432 | 1070.0 | 781.0 | 0.03886781 |
| 7 | 1424 | 1236.0 | 924.0 | 0.02750982 |
| 8 | 1259 | 826.0 | 638.0 | 0.06024096 |
| 9 | 1247 | 796.0 | 612.0 | 0.05173913 |
| 10 | 1141 | 560.0 | 409.0 | 0.08976378 |
| 11 | 963 | 820.0 | 627.0 | 0.06049822 |
| 12 | 897 | 588.0 | 443.0 | 0.08113590 |
| 13 | 746 | 1159.5 | 892.0 | 0.03335862 |
| 14 | 551 | 1324.0 | 995.0 | 0.03610060 |
| 15 | 542 | 1282.0 | 785.5 | 0.05035454 |
| 16 | 362 | 479.5 | 359.5 | 0.09965678 |
| 17 | 227 | 567.0 | 445.0 | 0.08333333 |
EMBEDDING_TITLE_PREFIX <- "UMAP"
x_column <- "x_umap_min_dist=0.1"
y_column <- "y_umap_min_dist=0.1"
GEOM_POINT_SIZE <- 0.2
p_embedding_leiden <- plot_embedding(
embedding = embedding[, c(x_column, y_column)],
color_values = embedding$leiden %>% as.factor(),
label = paste0(EMBEDDING_TITLE_PREFIX, "; Leiden"),
label_position = NULL,
show_color_value_labels = TRUE,
show_color_legend = FALSE,
geom_point_size = GEOM_POINT_SIZE,
geom_point_alpha = 1,
sort_values = FALSE,
shuffle_values = FALSE,
label_size = 6,
label_hjust = 0,
label_vjust = 0,
rasterise = TRUE,
dpi = 600,
legend_size = 3,
legend_ncol = 2
) +
theme_customized()
p_embedding_UMI <- plot_embedding(
embedding = embedding[, c(x_column, y_column)],
color_values = embedding$num_umis %>% log10(),
label = paste0(EMBEDDING_TITLE_PREFIX, "; UMIs"),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5)
p_embedding_MT <- plot_embedding(
embedding = embedding[, c(x_column, y_column)],
color_values = embedding$mt_ratio,
label = paste0(EMBEDDING_TITLE_PREFIX, "; MT %"),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5)
list(
p_embedding_leiden,
p_embedding_UMI,
p_embedding_MT
) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(nrow = 1) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)barcode_location %<>%
left_join(
embedding %>% select(cell, leiden),
by = c("barcode" = "cell")
)GEOM_POINT_SIZE <- 0.3
p_spatial_na <- plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = as.numeric(is.na(barcode_location$leiden)) %>% as.factor(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
guides(colour = guide_legend(override.aes = list(size = 2), nrow = 2, title = NULL)) +
theme_customized(x = 0.02, legend_key_size = 1, legend_text_size = 5) +
theme_customized_void() %+replace%
theme(
legend.justification = 0.5,
legend.position = "bottom"
) +
scale_color_manual(
values = c("grey70", "salmon"),
labels = c("incl.", "not incl.")
)p_spatial_cluster <- plot_embedding(
embedding = barcode_location %>%
dplyr::select(x_coord, y_coord),
color_values = barcode_location$leiden %>% as.factor(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = FALSE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
guides(colour = guide_legend(override.aes = list(size = 2), nrow = 2, title = NULL)) +
theme_customized(legend_key_size = 1, legend_text_size = 5) %+replace%
theme_customized_void() %+replace%
theme(
legend.justification = 0.5,
legend.position = "bottom"
)Clustering; cells with lower UMI counts and higher MT percentages are discarded.
list(
p_spatial_na,
p_spatial_cluster
) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(ncol = 2) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)GEOM_POINT_SIZE <- 0.3
purrr::map(sort(unique(embedding$leiden)), function(x) {
values <- barcode_location$leiden == x
# values <- values[! is.na(values)]
values[is.na(values)] <- FALSE
plot_embedding(
embedding = barcode_location %>%
# dplyr::filter(! is.na(leiden)) %>%
dplyr::select(x_coord, y_coord),
color_values = as.numeric(values) %>% as.factor(),
show_color_legend = TRUE,
geom_point_size = GEOM_POINT_SIZE,
sort_values = TRUE,
rasterise = TRUE,
dpi = 600
) +
coord_fixed(
xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
) +
theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
theme_customized_void() +
scale_color_manual(
values = c("grey70", "salmon"),
labels = c("Other", x)
)
}) %>%
purrr::reduce(`+`) +
patchwork::plot_layout(ncol = 3) +
patchwork::plot_annotation(
theme = theme(plot.margin = margin())
)