cells <- read_fst(file.path(post_dir, "did-example-cells.fst")) |> as_tibble()
examples <- tibble::tribble(
~PatientID, ~response, ~BiopsyPhase, ~ImageID, ~prop,
"NT218", "pCR", "Baseline", "NTImg1578", "M2 4.0%\nPD-L1+ APCs 12.3%",
"NT218", "pCR", "Baseline", "NTImg1579", "M2 4.0%\nPD-L1+ APCs 12.3%",
"NT218", "pCR", "Baseline", "NTImg1580", "M2 4.0%\nPD-L1+ APCs 12.3%",
"NT218", "pCR", "Post-treatment", "NTImg0491", "M2 42.4%\nPD-L1+ APCs 0.7%",
"NT218", "pCR", "Post-treatment", "NTImg0493", "M2 42.4%\nPD-L1+ APCs 0.7%",
"NT215", "pCR", "Baseline", "NTImg1181", "M2 11.1%\nPD-L1+ APCs 10.2%",
"NT215", "pCR", "Baseline", "NTImg1182", "M2 11.1%\nPD-L1+ APCs 10.2%",
"NT215", "pCR", "Baseline", "NTImg1183", "M2 11.1%\nPD-L1+ APCs 10.2%",
"NT215", "pCR", "Post-treatment", "NTImg0366", "M2 45.8%\nPD-L1+ APCs 0.4%",
"NT215", "pCR", "Post-treatment", "NTImg0372", "M2 45.8%\nPD-L1+ APCs 0.4%",
"NT215", "pCR", "Post-treatment", "NTImg0378", "M2 45.8%\nPD-L1+ APCs 0.4%",
"NT174", "RD", "Baseline", "NTImg1824", "M2 2.0%\nPD-L1+ APCs 2.1%",
"NT174", "RD", "Baseline", "NTImg1825", "M2 2.0%\nPD-L1+ APCs 2.1%",
"NT174", "RD", "Baseline", "NTImg1826", "M2 2.0%\nPD-L1+ APCs 2.1%",
"NT174", "RD", "Post-treatment", "NTImg0540", "M2 1.6%\nPD-L1+ APCs 0.8%",
"NT174", "RD", "Post-treatment", "NTImg0542", "M2 1.6%\nPD-L1+ APCs 0.8%",
"NT028", "RD", "Baseline", "NTImg1317", "M2 12.3%\nPD-L1+ APCs 1.8%",
"NT028", "RD", "Baseline", "NTImg1318", "M2 12.3%\nPD-L1+ APCs 1.8%",
"NT028", "RD", "Baseline", "NTImg1319", "M2 12.3%\nPD-L1+ APCs 1.8%",
"NT028", "RD", "Post-treatment", "NTImg0385", "M2 12.6%\nPD-L1+ APCs 1.9%",
"NT028", "RD", "Post-treatment", "NTImg0387", "M2 12.6%\nPD-L1+ APCs 1.9%"
)
tile_pt <- c(other = 0.22, pdl1 = 0.40, m2 = 0.40)
mk_note <- function(text, size = 2.7, face = "plain") {
ggplot() +
annotate(
"text", x = 0.5, y = 0.5, label = text,
fontface = face, size = size, lineheight = 0.95
) +
scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) +
scale_y_continuous(limits = c(0, 1), expand = c(0, 0)) +
theme_void()
}
mk_phase <- function(pid, phase) {
ids <- examples |>
filter(PatientID == pid, BiopsyPhase == phase) |>
pull(ImageID)
ids <- c(ids, rep(NA_character_, 3L - length(ids)))
tiles <- lapply(ids, function(id) {
if (is.na(id)) return(patchwork::plot_spacer())
mk_spatial_tile(filter(cells, ImageID == id), pt = tile_pt)
})
prop <- examples$prop[examples$PatientID == pid & examples$BiopsyPhase == phase][1]
patchwork::wrap_plots(
mk_note(prop, size = 2.5),
patchwork::wrap_plots(tiles, nrow = 1),
ncol = 1,
heights = c(0.22, 1)
)
}
mk_patient <- function(pid) {
response <- examples$response[examples$PatientID == pid][1]
patchwork::wrap_plots(
mk_note(paste0(pid, "\n", response), size = 3.1, face = "bold"),
mk_phase(pid, "Baseline"),
mk_phase(pid, "Post-treatment"),
nrow = 1,
widths = c(0.55, 3, 3)
)
}
header <- patchwork::wrap_plots(
patchwork::plot_spacer(),
mk_note("Baseline", size = 3.4, face = "bold"),
mk_note("Post-treatment", size = 3.4, face = "bold"),
nrow = 1,
widths = c(0.55, 3, 3)
)
patchwork::wrap_plots(
header,
mk_patient("NT218"),
mk_patient("NT215"),
mk_patient("NT174"),
mk_patient("NT028"),
ncol = 1,
heights = c(0.28, 1, 1, 1, 1)
) +
patchwork::plot_annotation(
title = "Change from baseline in four chemoimmunotherapy patients",
subtitle = "Magenta: M2 macrophages. Yellow: PD-L1-positive APCs. Green: other immune cells.",
theme = theme(
plot.title = element_text(face = "bold", size = 13),
plot.subtitle = element_text(size = 10, colour = "grey25")
)
)