ggplot(data = d)+
facet_wrap(facets = ~paste0("compound=", compound),
scales = "free_y", ncol = 2)+
geom_sina(aes(x = as.factor(dose), col = plate, y = v, group = well),
size = 0.5)+
theme_bw()+
theme(legend.position = "top",
strip.text.x = element_text(margin = margin(0.03,0,0.03,0, "cm")))+
ylab(label = "migration velocity")+
xlab(label = '')+
scale_color_grey()+
guides(color = guide_legend(override.aes = list(size = 3)))+
guides(shape = guide_legend(override.aes = list(size = 3)))+
scale_y_log10()+
annotation_logticks(base = 10, sides = "l")
Create experimental ``artifact’’ -> merge C2 and C6 to create a
bimodal velocity distribution
c6 <- d[d$compound == "C6",]
c2 <- d[d$compound == "C2",]
c6$well <- c2$well
c6$v <- c6$v+20
c6$compound <- "C2"
q <- d[d$compound != "C6",]
q <- rbind(q, c6)
d <- q
ggplot(data = d)+
facet_wrap(facets = ~paste0("compound=", compound),
scales = "free_y", ncol = 2)+
geom_sina(aes(x = as.factor(dose), col = plate, y = v, group = well),
size = 0.5)+
theme_bw()+
theme(legend.position = "top",
strip.text.x = element_text(margin = margin(0.03,0,0.03,0, "cm")))+
ylab(label = "migration velocity")+
xlab(label = '')+
scale_color_grey()+
guides(color = guide_legend(override.aes = list(size = 3)))+
guides(shape = guide_legend(override.aes = list(size = 3)))+
scale_y_log10()+
annotation_logticks(base = 10, sides = "l")

o <- cellmig(x = d,
control = list(mcmc_warmup = 300, # Warmup iterations
mcmc_steps = 1000, # Sampling iterations
mcmc_chains = 2, # Number of chains
mcmc_cores = 2)) # Parallel cores
ggplot(data = o$posteriors$delta_t) +
geom_line(aes(x = dose, y = mean, col = compound, group = compound)) +
geom_point(aes(x = dose, y = mean, col = compound)) +
geom_errorbar(aes(x = dose, y = mean, ymin = X2.5., ymax = X97.5.,
col = compound), width = 0.1) +
ylab(label = expression("Log-Fold Change ("*delta*")")) +
xlab("Dose") +
theme(legend.position = "top")

g <- get_ppc_violins(x = o, wrap = TRUE, ncol = 3)
g + scale_y_log10()

g <- get_ppc_means(x = o)
g

# Plate-specific baseline effects
g_alpha_p <- ggplot(data = o$posteriors$alpha_p) +
geom_errorbarh(aes(y = plate, x = mean, xmin = X2.5., xmax = X97.5.),
height = 0.2) +
geom_point(aes(y = plate, x = mean)) +
xlab("Plate Effect (log-scale)")
# Variance parameters (Biological vs Technical)
g_sigma <- ggplot() +
geom_errorbarh(data = o$posteriors$sigma_bio,
aes(y = "Biological (Plate)",
x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
geom_errorbarh(data = o$posteriors$sigma_tech,
aes(y = "Technical (Well)",
x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
geom_errorbarh(data = o$posteriors$sigma_delta,
aes(y = "Treatment Variation",
x = mean, xmin = X2.5., xmax = X97.5.), height = 0.2) +
geom_point(data = o$posteriors$sigma_bio,
aes(y = "Biological (Plate)", x = mean)) +
geom_point(data = o$posteriors$sigma_tech,
aes(y = "Technical (Well)", x = mean)) +
geom_point(data = o$posteriors$sigma_delta,
aes(y = "Treatment Variation", x = mean)) +
xlab("Standard Deviation")
g_alpha_p | g_sigma

Session Info
FALSE R version 4.6.1 (2026-06-24)
FALSE Platform: x86_64-pc-linux-gnu
FALSE Running under: Ubuntu 26.04.1 LTS
FALSE
FALSE Matrix products: default
FALSE BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
FALSE LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
FALSE
FALSE locale:
FALSE [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
FALSE [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
FALSE [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
FALSE [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
FALSE [9] LC_ADDRESS=C LC_TELEPHONE=C
FALSE [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
FALSE
FALSE time zone: Etc/UTC
FALSE tzcode source: system (glibc)
FALSE
FALSE attached base packages:
FALSE [1] stats graphics grDevices utils datasets methods base
FALSE
FALSE other attached packages:
FALSE [1] rstan_2.32.7 StanHeaders_2.39.1 ggforce_0.5.0 ggplot2_4.0.3
FALSE [5] cellmig_1.3.9 BiocStyle_2.41.0
FALSE
FALSE loaded via a namespace (and not attached):
FALSE [1] ggiraph_0.9.6 tidyselect_1.2.1 dplyr_1.2.1
FALSE [4] farver_2.1.2 loo_2.10.1 S7_0.2.2
FALSE [7] fastmap_1.2.0 lazyeval_0.2.3 tensorA_0.36.2.1
FALSE [10] tweenr_2.0.3 fontquiver_0.2.1 digest_0.6.39
FALSE [13] lifecycle_1.0.5 tidytree_0.4.8 posterior_1.7.0
FALSE [16] magrittr_2.0.5 compiler_4.6.1 rlang_1.3.0
FALSE [19] sass_0.4.10 tools_4.6.1 yaml_2.3.12
FALSE [22] knitr_1.52 labeling_0.4.3 htmlwidgets_1.6.4
FALSE [25] pkgbuild_1.4.8 curl_8.0.0 plyr_1.8.9
FALSE [28] RColorBrewer_1.1-3 abind_1.4-8 aplot_0.3.1
FALSE [31] withr_3.0.3 purrr_1.2.2 sys_3.4.3
FALSE [34] grid_4.6.1 polyclip_1.10-7 stats4_4.6.1
FALSE [37] gdtools_0.5.1 inline_0.3.21 scales_1.4.0
FALSE [40] MASS_7.3-66 cli_3.6.6 rmarkdown_2.32
FALSE [43] treeio_1.37.0 generics_0.1.4 otel_0.2.0
FALSE [46] RcppParallel_6.2.1 ggtree_4.3.0 reshape2_1.4.5
FALSE [49] ape_5.8-1 cachem_1.1.0 stringr_1.6.0
FALSE [52] parallel_4.6.1 ggplotify_0.1.3 BiocManager_1.30.27
FALSE [55] matrixStats_1.5.0 vctrs_0.7.3 yulab.utils_0.2.5
FALSE [58] V8_8.2.0 jsonlite_2.0.0 fontBitstreamVera_0.1.1
FALSE [61] gridGraphics_0.5-1 patchwork_1.3.2 systemfonts_1.3.2
FALSE [64] maketools_1.3.2 tidyr_1.3.2 jquerylib_0.1.4
FALSE [67] glue_1.8.1 codetools_0.2-20 distributional_0.9.0
FALSE [70] stringi_1.8.9 gtable_0.3.6 QuickJSR_1.11.0
FALSE [73] tibble_3.3.1 pillar_1.11.1 rappdirs_0.3.4
FALSE [76] htmltools_0.5.9 R6_2.6.1 evaluate_1.0.5
FALSE [79] lattice_0.23-1 backports_1.5.1 ggfun_0.2.1
FALSE [82] fontLiberation_0.1.0 bslib_0.12.0 rstantools_2.7.1
FALSE [85] Rcpp_1.1.2 checkmate_2.3.4 gridExtra_2.3.1
FALSE [88] nlme_3.1-171 xfun_0.60 fs_2.1.0
FALSE [91] buildtools_1.0.0 pkgconfig_2.0.3