1. load libraries

2. Load Data into Seurat


ss_herrera <- readRDS("STCAT/All_Patients_Integrated_ss_Herrera_annotated.RDS")

3. Visualizations


# Manually enter your data as a named vector
prediction_counts <- c(
  "None T" = 9622,
  "CD4 Tcm" = 4935,
  "CD4 Tn" = 3927,
  "Tgd" = 1531,
  "CD8 Tn" = 1381,
  "CD8 Temra" = 1264,
  "CD4 Trm cell-death" = 1134,
  "CD4 Tex" = 906,
  "CD8 Tc" = 743,
  "CD4 Tisg" = 702,
  "CD8 Tem" = 669,
  "CD4 Trm" = 615,
  "CD8 Trm naive-like" = 476,
  "MAIT" = 385,
  "CD4 Tc" = 361,
  "CD4 Tem" = 272,
  "CD4 Treg" = 228,
  "CD4 Tn adhesion" = 163,
  "CD8 Trm" = 142,
  "CD4 Treg naive-like" = 142,
  "CD4 Th17" = 137,
  "CD8 proliferation" = 134,
  "CD4 proliferation" = 108,
  "CD4 Temra" = 62,
  "CD4 activated" = 40,
  "Double Negative" = 32,
  "CD4 Tfh" = 31,
  "CD8 Tstr" = 26,
  "CD8 Tcm" = 19,
  "other CD8 T" = 9,
  "CD8 senescence" = 4,
  "CD8 Tex" = 2
)

# Convert to data frame
df <- data.frame(
  Prediction = factor(names(prediction_counts), levels = names(sort(prediction_counts))),
  Count = prediction_counts
)

# Load ggplot2
library(ggplot2)

# Horizontal barplot (flipped coordinates)
ggplot(df, aes(x = Count, y = Prediction)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  labs(
    title = "Cell Type Predictions from STCAT",
    x = "Number of Cells",
    y = "Predicted Cell Type"
  ) +
  theme(axis.text.y = element_text(size = 8))

NA
NA

Dimplot


DimPlot(ss_herrera, group.by = "tissue", label = TRUE, repel = T,label.box = T)

DimPlot(ss_herrera, group.by = "sample_id", label = TRUE, repel = T,label.box = T)

DimPlot(ss_herrera, group.by = "RNA_snn_res.0.5", label = TRUE, repel = T, label.box = T)

DimPlot(ss_herrera, group.by = "STCAT_Prediction", label = F, repel = F, label.box = T)

Distributions


table(ss_herrera$STCAT_Prediction)  # should show all predicted labels

      CD4 activated   CD4 proliferation              CD4 Tc             CD4 Tcm             CD4 Tem           CD4 Temra 
                 40                 108                 361                4935                 272                  62 
            CD4 Tex             CD4 Tfh            CD4 Th17            CD4 Tisg              CD4 Tn     CD4 Tn adhesion 
                906                  31                 137                 702                3927                 163 
           CD4 Treg CD4 Treg naive-like             CD4 Trm  CD4 Trm cell-death   CD8 proliferation      CD8 senescence 
                228                 142                 615                1134                 134                   4 
             CD8 Tc             CD8 Tcm             CD8 Tem           CD8 Temra             CD8 Tex              CD8 Tn 
                743                  19                 669                1264                   2                1381 
            CD8 Trm  CD8 Trm naive-like            CD8 Tstr     Double Negative                MAIT              None T 
                142                 476                  26                  32                 385                9622 
        other CD8 T                 Tgd 
                  9                1531 
table(ss_herrera$sample_id)         # should show L1–L7

Healthy_Blood  Healthy_Skin     MF1_Blood      MF1_Skin     SS1_Blood      SS1_Skin     SS2_Blood      SS2_Skin 
         4386            33          4880           293          3631           374          6078           244 
    SS3_Blood      SS3_Skin     SS4_Blood      SS4_Skin     SS5_Blood     SS6_Blood 
         2109           272          2072           320          2832          2821 
table(ss_herrera$tissue) 

Blood  Skin 
28809  1536 
# Contingency table 
table_annotation_tissue <- table(ss_herrera$STCAT_Prediction, ss_herrera$tissue)
table_annotation_sample_id <- table(ss_herrera$STCAT_Prediction, ss_herrera$sample_id)
table_annotation_cluster <- table(ss_herrera$STCAT_Prediction, ss_herrera$RNA_snn_res.0.5)

library(pheatmap)

# Proportion table (color scale)
prop_table <- prop.table(table_annotation_cluster, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_cluster,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Clusters")



library(pheatmap)

# Proportion table (color scale)
prop_table <- prop.table(table_annotation_sample_id, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_sample_id,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Patients")



# Proportion table (color scale)
prop_table <- prop.table(table_annotation_tissue, margin = 1)

# Heatmap with raw counts as labels
pheatmap(prop_table,
         display_numbers = table_annotation_tissue,
         cluster_rows = TRUE,
         cluster_cols = TRUE,
         color = colorRampPalette(c("lightyellow", "yellow", "lightgreen", "white"))(100),
         fontsize_row = 10,
         fontsize_col = 10,
         main = "STCAT Prediction vs Patients")

NA
NA


library(ggplot2)
library(ggridges)

ggplot(ss_herrera@meta.data, aes(x = STCAT_Uncertainty, y = STCAT_Prediction, fill = STCAT_Prediction)) +
  geom_density_ridges(alpha = 0.7, scale = 2, rel_min_height = 0.01) +
  theme_minimal() +
  labs(
    x = "Cluster Entropy Score",
    y = "Predicted T Cell Type (STCAT)",
    title = "Density Ridgeline of Cluster Entropy by T Cell Type"
  ) +
  theme(
    legend.position = "none",
    axis.text.y = element_text(size = 9)
  )

NA
NA
LS0tCnRpdGxlOiAiU1RDQVRfSGVycmVyYV9WaXN1YWxpemF0aW9uIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICNybWRmb3JtYXRzOjpyZWFkdGhlZG93bgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQotLS0KCiMgMS4gbG9hZCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShybWFya2Rvd24pCmxpYnJhcnkodGlueXRleCkKCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGRpdHRvU2VxKQpsaWJyYXJ5KGdncmVwZWwpCiNsaWJyYXJ5KGdndHJlZSkKbGlicmFyeShwYXJhbGxlbCkKbGlicmFyeShwbG90bHkpICAjIDNEIHBsb3QKbGlicmFyeShTZXVyYXQpICAjIElkZW50cygpCmxpYnJhcnkoU2V1cmF0RGlzaykgICMgU2F2ZUg1U2V1cmF0KCkKbGlicmFyeSh0aWJibGUpICAjIHJvd25uYW1lc190b19jb2x1bW4KbGlicmFyeShoYXJtb255KSAjIFJ1bkhhcm1vbnkoKQojb3B0aW9ucyhtYy5jb3JlcyA9IGRldGVjdENvcmVzKCkgLSAxKQoKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoZGJwbHlyKQpsaWJyYXJ5KHJtYXJrZG93bikKbGlicmFyeShrbml0cikKbGlicmFyeSh0aW55dGV4KQojQXppbXV0aCBBbm5vdGF0aW9uIGxpYnJhcmllcwpsaWJyYXJ5KEF6aW11dGgpCiNQcm9qZWNUaWxzIEFubm90YXRpb24gbGlicmFyaWVzCmxpYnJhcnkoU1RBQ0FTKQpsaWJyYXJ5KFByb2plY1RJTHMpCiNzaW5nbGVSIEFubm90YXRpb24gbGlicmFyaWVzCgpsaWJyYXJ5KFNpbmdsZUNlbGxFeHBlcmltZW50KQoKYGBgCgoKIyAyLiBMb2FkIERhdGEgaW50byBTZXVyYXQKYGBge3IgbG9hZF9zZXVyYXR9Cgpzc19oZXJyZXJhIDwtIHJlYWRSRFMoIlNUQ0FUL0FsbF9QYXRpZW50c19JbnRlZ3JhdGVkX3NzX0hlcnJlcmFfYW5ub3RhdGVkLlJEUyIpCgpgYGAKCiMgMy4gVmlzdWFsaXphdGlvbnMgCmBgYHtyIFNUQ0FUX3ZpcywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KCiMgTWFudWFsbHkgZW50ZXIgeW91ciBkYXRhIGFzIGEgbmFtZWQgdmVjdG9yCnByZWRpY3Rpb25fY291bnRzIDwtIGMoCiAgIk5vbmUgVCIgPSA5NjIyLAogICJDRDQgVGNtIiA9IDQ5MzUsCiAgIkNENCBUbiIgPSAzOTI3LAogICJUZ2QiID0gMTUzMSwKICAiQ0Q4IFRuIiA9IDEzODEsCiAgIkNEOCBUZW1yYSIgPSAxMjY0LAogICJDRDQgVHJtIGNlbGwtZGVhdGgiID0gMTEzNCwKICAiQ0Q0IFRleCIgPSA5MDYsCiAgIkNEOCBUYyIgPSA3NDMsCiAgIkNENCBUaXNnIiA9IDcwMiwKICAiQ0Q4IFRlbSIgPSA2NjksCiAgIkNENCBUcm0iID0gNjE1LAogICJDRDggVHJtIG5haXZlLWxpa2UiID0gNDc2LAogICJNQUlUIiA9IDM4NSwKICAiQ0Q0IFRjIiA9IDM2MSwKICAiQ0Q0IFRlbSIgPSAyNzIsCiAgIkNENCBUcmVnIiA9IDIyOCwKICAiQ0Q0IFRuIGFkaGVzaW9uIiA9IDE2MywKICAiQ0Q4IFRybSIgPSAxNDIsCiAgIkNENCBUcmVnIG5haXZlLWxpa2UiID0gMTQyLAogICJDRDQgVGgxNyIgPSAxMzcsCiAgIkNEOCBwcm9saWZlcmF0aW9uIiA9IDEzNCwKICAiQ0Q0IHByb2xpZmVyYXRpb24iID0gMTA4LAogICJDRDQgVGVtcmEiID0gNjIsCiAgIkNENCBhY3RpdmF0ZWQiID0gNDAsCiAgIkRvdWJsZSBOZWdhdGl2ZSIgPSAzMiwKICAiQ0Q0IFRmaCIgPSAzMSwKICAiQ0Q4IFRzdHIiID0gMjYsCiAgIkNEOCBUY20iID0gMTksCiAgIm90aGVyIENEOCBUIiA9IDksCiAgIkNEOCBzZW5lc2NlbmNlIiA9IDQsCiAgIkNEOCBUZXgiID0gMgopCgojIENvbnZlcnQgdG8gZGF0YSBmcmFtZQpkZiA8LSBkYXRhLmZyYW1lKAogIFByZWRpY3Rpb24gPSBmYWN0b3IobmFtZXMocHJlZGljdGlvbl9jb3VudHMpLCBsZXZlbHMgPSBuYW1lcyhzb3J0KHByZWRpY3Rpb25fY291bnRzKSkpLAogIENvdW50ID0gcHJlZGljdGlvbl9jb3VudHMKKQoKIyBMb2FkIGdncGxvdDIKbGlicmFyeShnZ3Bsb3QyKQoKIyBIb3Jpem9udGFsIGJhcnBsb3QgKGZsaXBwZWQgY29vcmRpbmF0ZXMpCmdncGxvdChkZiwgYWVzKHggPSBDb3VudCwgeSA9IFByZWRpY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic3RlZWxibHVlIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkNlbGwgVHlwZSBQcmVkaWN0aW9ucyBmcm9tIFNUQ0FUIiwKICAgIHggPSAiTnVtYmVyIG9mIENlbGxzIiwKICAgIHkgPSAiUHJlZGljdGVkIENlbGwgVHlwZSIKICApICsKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgoKYGBgCgoKIyMgRGltcGxvdApgYGB7ciBTVENBVF92aXMyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQoKRGltUGxvdChzc19oZXJyZXJhLCBncm91cC5ieSA9ICJ0aXNzdWUiLCBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVCxsYWJlbC5ib3ggPSBUKQpEaW1QbG90KHNzX2hlcnJlcmEsIGdyb3VwLmJ5ID0gInNhbXBsZV9pZCIsIGxhYmVsID0gVFJVRSwgcmVwZWwgPSBULGxhYmVsLmJveCA9IFQpCkRpbVBsb3Qoc3NfaGVycmVyYSwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMC41IiwgbGFiZWwgPSBUUlVFLCByZXBlbCA9IFQsIGxhYmVsLmJveCA9IFQpCkRpbVBsb3Qoc3NfaGVycmVyYSwgZ3JvdXAuYnkgPSAiU1RDQVRfUHJlZGljdGlvbiIsIGxhYmVsID0gRiwgcmVwZWwgPSBGLCBsYWJlbC5ib3ggPSBUKQpgYGAKCiMjIERpc3RyaWJ1dGlvbnMKYGBge3IgU1RDQVRfdmlzMywgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTE0fQoKdGFibGUoc3NfaGVycmVyYSRTVENBVF9QcmVkaWN0aW9uKSAgIyBzaG91bGQgc2hvdyBhbGwgcHJlZGljdGVkIGxhYmVscwp0YWJsZShzc19oZXJyZXJhJHNhbXBsZV9pZCkgICAgICAgICAjIHNob3VsZCBzaG93IEwx4oCTTDcKdGFibGUoc3NfaGVycmVyYSR0aXNzdWUpIAoKIyBDb250aW5nZW5jeSB0YWJsZSAKdGFibGVfYW5ub3RhdGlvbl90aXNzdWUgPC0gdGFibGUoc3NfaGVycmVyYSRTVENBVF9QcmVkaWN0aW9uLCBzc19oZXJyZXJhJHRpc3N1ZSkKdGFibGVfYW5ub3RhdGlvbl9zYW1wbGVfaWQgPC0gdGFibGUoc3NfaGVycmVyYSRTVENBVF9QcmVkaWN0aW9uLCBzc19oZXJyZXJhJHNhbXBsZV9pZCkKdGFibGVfYW5ub3RhdGlvbl9jbHVzdGVyIDwtIHRhYmxlKHNzX2hlcnJlcmEkU1RDQVRfUHJlZGljdGlvbiwgc3NfaGVycmVyYSRSTkFfc25uX3Jlcy4wLjUpCgpsaWJyYXJ5KHBoZWF0bWFwKQoKIyBQcm9wb3J0aW9uIHRhYmxlIChjb2xvciBzY2FsZSkKcHJvcF90YWJsZSA8LSBwcm9wLnRhYmxlKHRhYmxlX2Fubm90YXRpb25fY2x1c3RlciwgbWFyZ2luID0gMSkKCiMgSGVhdG1hcCB3aXRoIHJhdyBjb3VudHMgYXMgbGFiZWxzCnBoZWF0bWFwKHByb3BfdGFibGUsCiAgICAgICAgIGRpc3BsYXlfbnVtYmVycyA9IHRhYmxlX2Fubm90YXRpb25fY2x1c3RlciwKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gVFJVRSwKICAgICAgICAgY2x1c3Rlcl9jb2xzID0gVFJVRSwKICAgICAgICAgY29sb3IgPSBjb2xvclJhbXBQYWxldHRlKGMoImxpZ2h0eWVsbG93IiwgInllbGxvdyIsICJsaWdodGdyZWVuIiwgIndoaXRlIikpKDEwMCksCiAgICAgICAgIGZvbnRzaXplX3JvdyA9IDEwLAogICAgICAgICBmb250c2l6ZV9jb2wgPSAxMCwKICAgICAgICAgbWFpbiA9ICJTVENBVCBQcmVkaWN0aW9uIHZzIENsdXN0ZXJzIikKCgpsaWJyYXJ5KHBoZWF0bWFwKQoKIyBQcm9wb3J0aW9uIHRhYmxlIChjb2xvciBzY2FsZSkKcHJvcF90YWJsZSA8LSBwcm9wLnRhYmxlKHRhYmxlX2Fubm90YXRpb25fc2FtcGxlX2lkLCBtYXJnaW4gPSAxKQoKIyBIZWF0bWFwIHdpdGggcmF3IGNvdW50cyBhcyBsYWJlbHMKcGhlYXRtYXAocHJvcF90YWJsZSwKICAgICAgICAgZGlzcGxheV9udW1iZXJzID0gdGFibGVfYW5ub3RhdGlvbl9zYW1wbGVfaWQsCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IFRSVUUsCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShjKCJsaWdodHllbGxvdyIsICJ5ZWxsb3ciLCAibGlnaHRncmVlbiIsICJ3aGl0ZSIpKSgxMDApLAogICAgICAgICBmb250c2l6ZV9yb3cgPSAxMCwKICAgICAgICAgZm9udHNpemVfY29sID0gMTAsCiAgICAgICAgIG1haW4gPSAiU1RDQVQgUHJlZGljdGlvbiB2cyBQYXRpZW50cyIpCgoKIyBQcm9wb3J0aW9uIHRhYmxlIChjb2xvciBzY2FsZSkKcHJvcF90YWJsZSA8LSBwcm9wLnRhYmxlKHRhYmxlX2Fubm90YXRpb25fdGlzc3VlLCBtYXJnaW4gPSAxKQoKIyBIZWF0bWFwIHdpdGggcmF3IGNvdW50cyBhcyBsYWJlbHMKcGhlYXRtYXAocHJvcF90YWJsZSwKICAgICAgICAgZGlzcGxheV9udW1iZXJzID0gdGFibGVfYW5ub3RhdGlvbl90aXNzdWUsCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IFRSVUUsCiAgICAgICAgIGNsdXN0ZXJfY29scyA9IFRSVUUsCiAgICAgICAgIGNvbG9yID0gY29sb3JSYW1wUGFsZXR0ZShjKCJsaWdodHllbGxvdyIsICJ5ZWxsb3ciLCAibGlnaHRncmVlbiIsICJ3aGl0ZSIpKSgxMDApLAogICAgICAgICBmb250c2l6ZV9yb3cgPSAxMCwKICAgICAgICAgZm9udHNpemVfY29sID0gMTAsCiAgICAgICAgIG1haW4gPSAiU1RDQVQgUHJlZGljdGlvbiB2cyB0aXNzdWUiKQoKCmBgYAoKCgojIyAKYGBge3IgLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTR9CgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dyaWRnZXMpCgpnZ3Bsb3Qoc3NfaGVycmVyYUBtZXRhLmRhdGEsIGFlcyh4ID0gU1RDQVRfVW5jZXJ0YWludHksIHkgPSBTVENBVF9QcmVkaWN0aW9uLCBmaWxsID0gU1RDQVRfUHJlZGljdGlvbikpICsKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGFscGhhID0gMC43LCBzY2FsZSA9IDIsIHJlbF9taW5faGVpZ2h0ID0gMC4wMSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHggPSAiQ2x1c3RlciBFbnRyb3B5IFNjb3JlIiwKICAgIHkgPSAiUHJlZGljdGVkIFQgQ2VsbCBUeXBlIChTVENBVCkiLAogICAgdGl0bGUgPSAiRGVuc2l0eSBSaWRnZWxpbmUgb2YgQ2x1c3RlciBFbnRyb3B5IGJ5IFQgQ2VsbCBUeXBlIgogICkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpCiAgKQoKCmBgYAoKCgoKCg==