Figure 1 (B)

# Load the library
library(aplotExtra)
library(tidyverse)
library(ggfun)
library(readxl)
# Define functions and parameters
common_theme <- theme(
  legend.position = "none",
  axis.text.x = element_text(angle = 20, hjust = 1, size = 12, colour = "black")
)
params_tbl <- tribble(
  ~type,   ~d_id, ~col, ~low,       ~high,
  "bar",   "d2",   2,   "#FFFFE5", "#cc4c02",
  "point", "d1",   3,   "#FFFFE5", "#cc4c02",
  "bar",   "d2",   4,   "#D0E9C6", "#4CAF50",
  "bar",   "d2",   6,   "#D0E9C6", "#4CAF50",
  "point", "d1",   7,   "#D0E9C6", "#4CAF50",
  "point", "d1",   8,   "#BBDEFB", "#2196F3",
  "point", "d1",   9,   "#BBDEFB", "#2196F3",
  "point", "d1",   10,  "#BBDEFB", "#2196F3",
  "bar",   "d2",   8,   "#CAC0E1", "#715EA9",
  "bar",   "d2",   10,  "#CAC0E1", "#715EA9",
  "point", "d1",   14,  "#CAC0E1", "#715EA9",
  "point", "d1",   15,  "#CAC0E1", "#715EA9"
)
custom_point <- function(d, col, low, high) {
  funky_point(d, col) +
    scale_size_continuous(limits = c(0, 1), range = c(1, 5)) +
    scale_fill_gradient(low = low, high = high) +
    common_theme
}
custom_bar <- function(d, col, low, high) {
  p <- funky_bar(d, col)
  p$layers <- p$layers[-length(p$layers)]
  p +
    geom_vline(xintercept = 1.2) +
    scale_fill_gradient(low = low, high = high) +
    common_theme
}
plot_heatmap <- function(d1, d2, params = params_tbl) {
  f1 <- funky_text(d1)
  plots_list <- pmap(params, function(type, d_id, col, low, high) {
    df <- if(d_id == "d1") d1 else d2
    if(type == "bar") {
      custom_bar(df, col, low, high)
    } else {
      custom_point(df, col, low, high)
    }
  })
  ordered <- c(list(f1), plots_list)
  do.call(funky_heatmap, c(ordered, list(
    options = list(
      theme_stamp(),
      ggfun::theme_blinds(
        colour = c('white','white','grey90','grey90'),
        axis = 'y',
        axis.line.x = ggplot2::element_line()
      )
    )
  )))
}
# Load the data and plot figure 
d1_file <- "heatmap1030.xlsx"
d2_file <- "heatmap1031.xlsx"
stopifnot(file.exists(d1_file), file.exists(d2_file))
d1 <- read_excel(d1_file) |> as.data.frame() |> tibble::column_to_rownames("Sample_name")
d2 <- read_excel(d2_file) |> as.data.frame()
plot_heatmap(d1, d2)

Figure 1 (C)

# Load the library
library(Seurat)
library(ggprism)
#set the color
custom_colors <- c(
  "Brain1 NV" = "#ED9F9B",
  "Brain1 SF" = "#E5A79A",
  "Brain2 NV" = "#F1D0C6",
  "Brain2 SF" = "#6E8FB2",
  "Brain3 NV" = "#8AB1D2",
  "Brain3 SF" = "#A6CDE4",
  "Brain4 NV" = "#D0E0EF",
  "Brain4 SF" = "#74B69F",
  "Brain5 NV" = "#80BA8A",
  "Brain5 SF" = "#9CD1C8",
  "Lung NV" = "#F1DFA4",
  "Lung SF" = "#CC88B0"
)
# Load the data
load("merged_10Brain_Lung.RData")
data <- merged_10Brain_Lung@meta.data[, c("nCount_RNA", "nFeature_RNA", "orig.ident")]
# Show the figure
p <- ggplot(data, aes(x = nCount_RNA, y = nFeature_RNA, color = orig.ident)) +
  stat_smooth(method = "loess", se = FALSE, size = 1.2) +
  labs(x = "number of UMI", y = "number of genes") +
  scale_color_manual(values = custom_colors) +
  theme_minimal() +
  theme_prism(base_size = 15) +
  theme(
    plot.title   = element_text(hjust = 0.5, size = 20, face = "bold"),
    axis.title   = element_text(size = 18, face = "bold"),
    axis.text    = element_text(size = 15, face = "bold"),
    legend.text  = element_text(size = 12, face = "bold"),
    plot.margin  = margin(25, 25, 25, 25)
  ) +
  guides(color = guide_legend(
    title       = "Platform",
    title.theme = element_text(size = 13, face = "bold"),
    label.theme = element_text(size = 12, face = "bold")
  ))
p

Figure 1 (D)

# Load the library
library(eulerr)
library(grid)
# Define functions and parameters
format_labels <- function(counts, digits = 4) {
  total <- sum(counts)
  if (total == 0) {
    out <- rep("0\n(0%)", length(counts))
    names(out) <- names(counts)
    return(out)
  }
  out <- paste0(counts, "\n(", signif(counts / total * 100, digits), "%)")
  names(out) <- names(counts)
  out
}
extract_barcodes <- function(seurat_obj, ident) {
  md <- seurat_obj@meta.data
  stopifnot("orig.ident" %in% colnames(md))
  cells <- rownames(md)[md$orig.ident == ident]
  sub(paste0("^", ident, "_"), "", cells)
}
analyze_barcode_overlap <- function(seurat_obj, sample1, sample2, percentage_digits = 4) {
  b1 <- unique(extract_barcodes(seurat_obj, sample1))
  b2 <- unique(extract_barcodes(seurat_obj, sample2))
  shared_n <- length(intersect(b1, b2))
  counts <- c(
    setNames(length(setdiff(b1, b2)), sample1),
    setNames(length(setdiff(b2, b1)), sample2),
    setNames(shared_n, paste(sample1, sample2, sep = "&"))
  )
  labels <- format_labels(counts, percentage_digits)
  list(data = counts, labels = labels)
}
plot_barcode_euler <- function(overlap_res, title = "Sample") {
  venn <- euler(overlap_res$data)
  venn_labels <- overlap_res$labels
  grid.newpage()
  p <- plot(
    venn,
    fills = list(fill = c("#F9DF91", "#A8CFE8", "#E6D9AE"), alpha = 0.7),
    labels = FALSE,
    edges = NULL, 
    quantities = FALSE,
    main = list(label = title, cex = 4, font = 2),
    output = "grob"
  )
  grid.draw(p)
  grid.text(venn_labels[1], x = 0.12, y = 0.5, gp = gpar(fontsize = 20, fontface = "bold"))
  grid.text(venn_labels[2], x = 0.88, y = 0.5, gp = gpar(fontsize = 20, fontface = "bold"))
  grid.text(venn_labels[3], x = 0.5,  y = 0.5, gp = gpar(fontsize = 40, fontface = "bold"))
}
#  Load data and show the figure
load("merged_all.RData")
res <- analyze_barcode_overlap(merged_R_9_24h_2, "Lung NV", "Lung SF")
plot_barcode_euler(res, title = "Lung")

Figure 1 (E)

# Define functions and parameters
plot_params <- list(
  gene_col = "nFeature_RNA",
  umi_col = "nCount_RNA",
  bar_colors = c("#F9DF91", "#E6D9AE", "#A8CFE8"),
  show_overall_median = TRUE
)
get_barcodes <- function(meta, ident) {
  cells <- rownames(meta)[meta$orig.ident == ident]
  sub(paste0(ident, "_"), "", cells)
}
prepare_data <- function(seurat_obj, sample1, sample2, gene_col, umi_col) {
  meta <- seurat_obj@meta.data
  barcodes1 <- get_barcodes(meta, sample1)
  barcodes2 <- get_barcodes(meta, sample2)
  shared  <- intersect(barcodes1, barcodes2)
  unique1 <- setdiff(barcodes1, shared)
  unique2 <- setdiff(barcodes2, shared)
  cells_sample1 <- paste0(sample1, "_", unique1)
  cells_sample2 <- paste0(sample2, "_", unique2)
  cells_shared  <- c(paste0(sample1, "_", shared), paste0(sample2, "_", shared))
  df <- data.frame(
    Cell_Group = factor(
      c(rep(paste0(sample1, " unique"), length(cells_sample1)),
        rep("Shared", length(cells_shared)),
        rep(paste0(sample2, " unique"), length(cells_sample2))),
      levels = c(paste0(sample1, " unique"), "Shared", paste0(sample2, " unique"))
    ),
    Gene_Count = c(meta[cells_sample1, gene_col],
                   meta[cells_shared, gene_col],
                   meta[cells_sample2, gene_col]),
    UMI_Count = c(meta[cells_sample1, umi_col],
                  meta[cells_shared, umi_col],
                  meta[cells_sample2, umi_col])
  )
  gene_medians <- tapply(df$Gene_Count, df$Cell_Group, median)
  gene_se <- tapply(df$Gene_Count, df$Cell_Group, function(x) mad(x) / sqrt(length(x)))
  overall_median <- median(df$Gene_Count)
  return(list(df = df, gene_medians = gene_medians, 
              gene_se = gene_se, overall_median = overall_median))
}
plot_count_barplot <- function(gene_medians, gene_se, overall_median, 
                               bar_colors, show_overall_median) {
  par(mar = c(5, 8, 5, 5))
  bp <- barplot(
    gene_medians,
    beside = TRUE,
    col = bar_colors,
    ylab = "Median gene count per cell",
    cex.main = 1.6, cex.axis = 1.2, cex.lab = 1.2,
    las = 2, font.lab = 2, font.axis = 2, font.main = 2,
    names.arg = FALSE
  )
  text(
    x = bp, 
    y = par("usr")[3] - 0.05 * diff(par("usr")[3:4]),
    labels = names(gene_medians),
    srt = 25, adj = 1, xpd = TRUE,
    cex = 1.1, font = 2
  )
  if (show_overall_median) {
    abline(h = overall_median, lty = 2, col = "red", lwd = 2)
  }
  arrows(
    x0 = bp, y0 = gene_medians - gene_se,
    x1 = bp, y1 = gene_medians + gene_se,
    angle = 90, code = 3, length = 0.1, lwd = 1.3
  )
}
# Show the figure
res <- prepare_data(
  seurat_obj = merged_R_9_24h_2,
  sample1 = "Lung NV",
  sample2 = "Lung SF",
  gene_col = plot_params$gene_col,
  umi_col  = plot_params$umi_col
)
plot_count_barplot(
  gene_medians = res$gene_medians,
  gene_se = res$gene_se,
  overall_median = res$overall_median,
  bar_colors = plot_params$bar_colors,
  show_overall_median = plot_params$show_overall_median
)

# package version 
library(sessioninfo)
pi <- package_info(pkgs = "attached")
pi_df <- as.data.frame(pi)[, c("package", "loadedversion", "source")]
pi_df
##                   package loadedversion         source
## aplotExtra     aplotExtra         0.0.4 CRAN (R 4.3.3)
## dplyr               dplyr         1.1.4 CRAN (R 4.3.3)
## eulerr             eulerr         7.0.2 CRAN (R 4.3.3)
## forcats           forcats         1.0.0 CRAN (R 4.3.1)
## ggfun               ggfun         0.1.8 CRAN (R 4.3.3)
## ggplot2           ggplot2         3.5.2 CRAN (R 4.3.3)
## ggprism           ggprism         1.0.6 CRAN (R 4.3.3)
## ggstar             ggstar         1.0.4 CRAN (R 4.3.1)
## lubridate       lubridate         1.9.4 CRAN (R 4.3.3)
## purrr               purrr         1.0.4 CRAN (R 4.3.3)
## readr               readr         2.1.5 CRAN (R 4.3.1)
## readxl             readxl         1.4.5 CRAN (R 4.3.3)
## sessioninfo   sessioninfo         1.2.3 CRAN (R 4.3.3)
## Seurat             Seurat         5.1.0 CRAN (R 4.3.3)
## SeuratObject SeuratObject         5.1.0 CRAN (R 4.3.3)
## sp                     sp         2.2-0 CRAN (R 4.3.3)
## stringr           stringr         1.5.1 CRAN (R 4.3.1)
## tibble             tibble         3.3.0 CRAN (R 4.3.3)
## tidyr               tidyr         1.3.1 CRAN (R 4.3.1)
## tidyverse       tidyverse         2.0.0 CRAN (R 4.3.3)